diff --git a/ROADMAP.md b/ROADMAP.md
index 591325a..5b3cdd0 100644
--- a/ROADMAP.md
+++ b/ROADMAP.md
@@ -1,7 +1,8 @@
# RSS Reader — Product Iteration Plan
> **Status**: Draft — v1.0.0 is live. This document defines the roadmap for subsequent releases.
-> **Tracking**: Each feature below corresponds to a GitHub Issue. Labels follow the pattern `iter/v1.x`.
+> **Tracking**: Each feature below corresponds to a GitHub Issue. Labels follow the pattern `iter/v1.x`.
+> **Competitive analysis**: See [Medium Comparison Report](docs/medium-comparison-report.md) for the detailed feature gap analysis that informed this roadmap.
---
@@ -81,6 +82,73 @@
---
+#### #3.1 · Reading progress bar *(new — from Medium comparison)*
+**Label**: `iter/v1.1`, `enhancement`
+**Description**: Display a thin progress bar at the top of the article detail page that fills as the user scrolls through the article, matching Medium's signature reading progress indicator.
+**Acceptance criteria**:
+- Fixed 3px bar at top of `ArticleDetailPage`
+- Smoothly fills from 0% to 100% based on scroll position
+- Colour adapts to current theme (green in light mode, blue in dark mode)
+- Uses `requestAnimationFrame` + passive scroll listener for performance
+- Stays at 100% when article is fully scrolled
+- Unit tested
+
+---
+
+#### #3.2 · Typography & readability upgrade *(new — from Medium comparison)*
+**Label**: `iter/v1.1`, `enhancement`
+**Description**: Refine article body typography to match Medium-level reading comfort: optimal line width (42rem), improved line-height for CJK content, larger base font size, and better heading hierarchy.
+**Acceptance criteria**:
+- Article body max-width reduced from 48rem to 42rem
+- Base font size: 18px desktop / 16px mobile
+- Line-height: 1.7 for CJK, 1.58 for Latin scripts
+- Heading sizes and spacing visually improved
+- No breaking changes to existing article rendering
+- Visual regression tested
+
+---
+
+#### #3.3 · Code syntax highlighting *(new — from Medium comparison)*
+**Label**: `iter/v1.1`, `enhancement`
+**Description**: Add syntax highlighting for code blocks inside articles using a lightweight library (e.g. highlight.js). Includes a copy-to-clipboard button on each code block.
+**Acceptance criteria**:
+- Code blocks in article HTML are auto-highlighted
+- Language auto-detected where possible
+- "Copy" button appears on hover/focus for each code block
+- Theme-aware (light/dark highlighting styles)
+- Bundle size increase ≤ 30 KB gzipped
+- Unit tested
+
+---
+
+#### #3.4 · Image lightbox *(new — from Medium comparison)*
+**Label**: `iter/v1.1`, `enhancement`
+**Description**: Allow users to click on images inside articles to view them in a full-screen lightbox overlay. Supports pinch-to-zoom on mobile.
+**Acceptance criteria**:
+- Clicking any `` in article body opens a full-screen overlay
+- Overlay supports swipe between images in the same article
+- Close via ESC key, backdrop click, or close button
+- Pinch-to-zoom on touch devices
+- Minimal bundle impact (use `medium-zoom` or equivalent, ~4 KB)
+- Unit tested
+
+---
+
+#### #3.5 · Enhanced article cards *(new — from Medium comparison)*
+**Label**: `iter/v1.1`, `enhancement`
+**Description**: Enrich article list cards with more metadata: thumbnail image, estimated reading time, 2-line summary preview, and visual unread/favourite indicators.
+**Acceptance criteria**:
+- Thumbnail image shown when available (lazy-loaded)
+- Reading time estimate displayed (clock icon + "X min")
+- Summary preview truncated to 2 lines
+- Unread articles: bold title + left blue accent bar
+- Favourited articles: heart badge on card corner
+- Hover: subtle lift + shadow animation
+- Responsive across mobile, tablet, desktop breakpoints
+- Unit tested
+
+---
+
## Iteration v1.2 — Content Enrichment (Priority: Medium)
**Goal**: Let users annotate, discover, and share content they find valuable.
@@ -123,6 +191,59 @@
---
+#### #6.1 · Recommended feed sources & onboarding *(new — from Medium comparison)*
+**Label**: `iter/v1.2`, `enhancement`
+**Description**: Provide a curated list of popular RSS feeds organised by category (Tech, Design, Business, Lifestyle, etc.) and show an onboarding flow for first-time users so they can subscribe to feeds without manually finding URLs.
+**Acceptance criteria**:
+- JSON config file with 6–8 categories, each containing 3–5 curated feeds
+- First-time user sees a step-by-step guide: Welcome → Pick categories → One-click subscribe → Enter main app
+- Onboarding can be skipped
+- `onboardingComplete` flag stored in localStorage to prevent re-display
+- Recommended feeds section also accessible from Settings for returning users
+- No external API calls required
+- Unit tested
+
+---
+
+#### #6.2 · Article table of contents (TOC) *(new — from Medium comparison)*
+**Label**: `iter/v1.2`, `enhancement`
+**Description**: Auto-generate a floating table of contents from article headings (h1–h3). Desktop: fixed right sidebar. Mobile: floating button that opens a drawer. Current heading highlighted based on scroll position.
+**Acceptance criteria**:
+- TOC only appears when article has ≥ 3 headings
+- Click TOC item → smooth scroll to heading
+- Current section highlighted via IntersectionObserver
+- Desktop: right-side sticky panel, does not overlap article body
+- Mobile: floating button → bottom drawer
+- Long headings truncated with ellipsis
+- Unit tested
+
+---
+
+#### #6.3 · Batch mark-as-read *(new — from Medium comparison)*
+**Label**: `iter/v1.2`, `enhancement`
+**Description**: Allow users to mark all articles as read at the feed or category level, and support multi-select mode for batch operations (mark read, favourite, delete).
+**Acceptance criteria**:
+- "Mark all as read" button on feed detail and category views
+- Long-press (mobile) or checkbox (desktop) enters multi-select mode
+- Batch actions: mark read, favourite, remove
+- Confirmation dialog before destructive batch actions
+- Unit tested
+
+---
+
+#### #6.4 · Pull-to-refresh on mobile *(new — from Medium comparison)*
+**Label**: `iter/v1.2`, `enhancement`
+**Description**: Implement native-feeling pull-to-refresh gesture on article list pages for mobile users, replacing the need to tap the refresh button.
+**Acceptance criteria**:
+- Pull down ≥ 60px at the top of the feed list triggers refresh
+- Animated spinner during refresh
+- Only active when scrolled to top
+- Works on iOS Safari and Android Chrome
+- Does not interfere with normal scrolling
+- Unit tested
+
+---
+
## Iteration v1.3 — Platform Expansion (Priority: Medium)
**Goal**: Reach users on more surfaces and make the product stickier across devices.
@@ -153,6 +274,48 @@
---
+#### #8.1 · Immersive reading mode *(new — from Medium comparison)*
+**Label**: `iter/v1.3`, `enhancement`
+**Description**: Provide a distraction-free reading mode that hides navigation, sidebars, and action bars, leaving only the article body and a floating back button. Triggered by a dedicated button or auto-hide on scroll-down.
+**Acceptance criteria**:
+- Hides: top navbar, sidebar, bottom action bar
+- Shows: article body only + floating "exit" button
+- Toggle via dedicated button in article toolbar
+- Auto-hide UI on scroll down, show on scroll up
+- ESC key exits immersive mode
+- Keyboard shortcut (`F11` or `z`) to toggle
+- Unit tested
+
+---
+
+#### #8.2 · Font & reading preferences *(new — from Medium comparison)*
+**Label**: `iter/v1.3`, `enhancement`
+**Description**: Allow users to customise article typography: font family (serif / sans-serif / system), font size (4 presets), and line spacing (3 presets). Persisted in localStorage and applied globally.
+**Acceptance criteria**:
+- Settings section: "Reading Preferences"
+- Font size: Small (14px) / Medium (16px) / Large (18px) / Extra Large (20px)
+- Font family: System Default / Serif / Sans-Serif
+- Line spacing: Compact / Normal / Relaxed
+- Stored in localStorage, applied to all article views
+- Preview in settings page
+- Unit tested
+
+---
+
+#### #8.3 · Multiple reading lists *(new — from Medium comparison)*
+**Label**: `iter/v1.3`, `enhancement`
+**Description**: Allow users to create named reading lists (e.g. "Read Later", "Tech Articles", "Weekend Reads") beyond the single favourites collection. Articles can be saved to one or more lists.
+**Acceptance criteria**:
+- Create / rename / delete reading lists
+- Save article to a specific list (or multiple lists)
+- Default list = existing Favourites (backwards compatible)
+- Dedicated page to browse all lists and their articles
+- Drag-to-reorder lists
+- Data stored in IndexedDB
+- Unit tested
+
+---
+
## Iteration v2.0 — New Content Formats (Priority: Low)
**Goal**: Expand beyond text articles to audio and email content.
@@ -205,11 +368,23 @@ Track these as separate issues with label `tech-debt`:
| #1 Reading time | Medium | Low | **High** |
| #2 Keyboard shortcuts | High | Low | **High** |
| #3 Advanced search | High | Medium | **High** |
+| #3.1 Reading progress bar | High | Very Low | **High** |
+| #3.2 Typography upgrade | High | Low | **High** |
+| #3.3 Code syntax highlighting | Medium | Low | **High** |
+| #3.4 Image lightbox | Medium | Very Low | **High** |
+| #3.5 Enhanced article cards | High | Low | **High** |
| #4 Annotations | High | High | Medium |
| #5 Feed discovery | Medium | Medium | Medium |
| #6 Social sharing | Medium | Low | **High** |
+| #6.1 Recommended feeds & onboarding | Very High | Medium | **High** |
+| #6.2 Article TOC | High | Medium | **High** |
+| #6.3 Batch mark-as-read | High | Low | **High** |
+| #6.4 Pull-to-refresh | Medium | Low | Medium |
| #7 Browser extension | High | High | Medium |
| #8 Multi-device sync | Very High | Very High | Low (needs backend) |
+| #8.1 Immersive reading mode | Medium | Low | Medium |
+| #8.2 Font & reading preferences | Medium | Low | Medium |
+| #8.3 Multiple reading lists | Medium | Medium | Medium |
| #9 Podcast | High | High | Low |
| #10 Newsletter | Medium | Very High | Low |
@@ -220,7 +395,8 @@ Track these as separate issues with label `tech-debt`:
1. **Product manager / repo owner**: Convert each issue section above into a GitHub Issue. Use the issue title, labels, and acceptance criteria verbatim.
2. **Developers**: Reference the acceptance criteria as the definition of done before opening a PR.
3. **Project board**: Create a GitHub Project with columns `Backlog → In Progress → Review → Done` and assign each issue to the appropriate iteration milestone.
+4. **Competitive analysis**: See [docs/medium-comparison-report.md](docs/medium-comparison-report.md) for the full feature gap analysis and rationale behind the new items marked *(from Medium comparison)*.
---
-*Last updated: 2026-03-02 · Maintainer: @chiga0*
+*Last updated: 2026-03-04 · Maintainer: @chiga0*
diff --git a/docs/medium-comparison-report.md b/docs/medium-comparison-report.md
new file mode 100644
index 0000000..9293057
--- /dev/null
+++ b/docs/medium-comparison-report.md
@@ -0,0 +1,642 @@
+# RSS Reader vs Medium — 功能对比报告与优化迭代计划
+
+> **版本**: v1.0
+> **日期**: 2026-03-04
+> **作者**: 产品经理
+> **状态**: 已完成
+> **目标读者**: 产品负责人、前端开发团队
+
+---
+
+## 目录
+
+1. [对比背景与方法论](#1-对比背景与方法论)
+2. [产品定位差异分析](#2-产品定位差异分析)
+3. [交互设计对比](#3-交互设计对比)
+4. [功能项详细对比](#4-功能项详细对比)
+5. [差距总结与优先级矩阵](#5-差距总结与优先级矩阵)
+6. [优化建议](#6-优化建议)
+7. [迭代计划](#7-迭代计划)
+8. [附录:竞品功能速查表](#8-附录竞品功能速查表)
+
+---
+
+## 1. 对比背景与方法论
+
+### 1.1 为什么对比 Medium?
+
+Medium 是全球最成功的博客/阅读平台之一,其核心优势在于:
+
+- **极致的阅读体验**:被公认为 Web 阅读体验的标杆
+- **内容发现机制**:算法推荐 + 人工编辑的混合模式
+- **社交互动设计**:Clap、Highlight、Response 三位一体
+- **增长飞轮**:读者 → 作者 → 内容 → 读者的正循环
+
+RSS Reader 作为去中心化的阅读工具,虽然产品定位不同,但 Medium 在**阅读体验、交互细节、内容组织**方面的设计值得深度借鉴。
+
+### 1.2 对比方法
+
+| 维度 | 对比方式 |
+|------|----------|
+| 交互设计 | 拆解用户旅程关键节点的交互细节 |
+| 功能完整度 | 逐项对比功能有/无及实现深度 |
+| 用户体验 | 从首次使用到日常使用的全链路分析 |
+| 技术实现 | 从前端实现角度评估可行性与工作量 |
+
+---
+
+## 2. 产品定位差异分析
+
+| 维度 | Medium | RSS Reader |
+|------|--------|------------|
+| **产品类型** | 中心化内容平台 | 去中心化阅读工具 (PWA) |
+| **内容来源** | 平台内创作 + 导入 | 任意 RSS/Atom 源 |
+| **核心价值** | 发现优质内容 + 写作发布 | 聚合阅读 + 信息管理 |
+| **商业模式** | 订阅制 (Member) | 免费/开源 |
+| **用户画像** | 泛阅读用户 + 创作者 | 信息效率型用户 / RSS 爱好者 |
+| **内容控制** | 平台算法控制 | 用户完全自主 |
+| **数据归属** | 平台持有 | 用户本地持有 (IndexedDB) |
+
+**核心差异**:Medium 追求"最好的阅读体验",RSS Reader 追求"最高效的信息获取"。两者可以在阅读体验层面互相借鉴,但不应在产品定位上趋同。
+
+---
+
+## 3. 交互设计对比
+
+### 3.1 首次使用体验 (Onboarding)
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **引导流程** | 注册后选择 3+ 兴趣话题,立即看到个性化内容 | 空白状态,需手动添加 Feed URL | 🔴 大 |
+| **空状态设计** | N/A(始终有内容) | 有空状态图标 + "添加 Feed" 按钮 | 🟡 中 |
+| **内容发现** | 话题推荐、编辑精选、热门文章 | 无内置推荐,需用户自行寻找 RSS 源 | 🔴 大 |
+| **上手成本** | 极低(选话题即可阅读) | 较高(需了解 RSS 概念和 Feed URL) | 🔴 大 |
+
+**优化方向**:增加"推荐订阅源"或"热门 Feed 精选"功能,降低新用户门槛。
+
+### 3.2 内容浏览与导航
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **信息流布局** | 单列卡片流(标题 + 摘要 + 配图 + 作者头像 + 阅读时长) | Feed 卡片网格(标题 + 描述 + 文章数) | 🟡 中 |
+| **文章预览卡片** | 丰富的元信息(Clap 数、阅读时长、作者、出版物、标签) | 基础信息(标题、发布时间、已读标记) | 🟡 中 |
+| **导航结构** | 首页 / 话题 / 通知 / 阅读列表 / 个人 | Feed 列表 / 收藏 / 历史 / 标注 / 搜索 / 设置 | 🟢 相当 |
+| **无限滚动** | ✅ 智能加载更多 | ❌ 一次性加载列表 | 🟡 中 |
+| **Tab 切换** | For You / Following / 各话题 Tab | 按分类筛选 | 🟢 相当 |
+| **面包屑/返回** | 浏览器后退 + 顶部返回 | 返回按钮 + 路由导航 | 🟢 相当 |
+
+### 3.3 文章阅读体验 ⭐ (最关键对比)
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **排版质量** | 顶级(自定义字体 Charter/Sohne、最优行宽 680px、行高 1.58、段间距 32px) | 良好(Tailwind prose、max-w-3xl=48rem、系统字体) | 🟡 中 |
+| **阅读进度指示** | 顶部绿色进度条(已读百分比) | ❌ 无 | 🔴 大 |
+| **预计阅读时长** | ✅ 文章标题下方显示 "X min read" | ❌ 无(ROADMAP v1.1 计划中) | 🟡 中 |
+| **目录大纲 (TOC)** | 右侧浮动目录(长文自动生成) | ❌ 无 | 🔴 大 |
+| **文内锚点导航** | 标题自动生成 anchor | ❌ 无 | 🟡 中 |
+| **代码块** | 语法高亮 + 复制按钮 | 基础渲染(prose 样式) | 🟡 中 |
+| **图片处理** | 响应式 + 懒加载 + 点击放大 + 图片说明 | 响应式 + 基础渲染 | 🟡 中 |
+| **嵌入内容** | YouTube、Twitter、Gist 等嵌入式预览 | ❌ 不支持 | 🟡 中 |
+| **文字选中交互** | 选中文字 → 弹出 Highlight/Tweet/Note 工具栏 | 选中文字 → 弹出 Highlight 颜色选择 | 🟢 相当 |
+| **页脚推荐** | "More from Author" + "Recommended" 推荐区 | ❌ 无 | 🟡 中 |
+| **字体/字号调整** | ❌ 无(设计已优化,不需要) | ❌ 无 | 🟡 中 |
+
+### 3.4 互动与反馈
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **点赞/反应** | Clap(可多次,最多 50 次) + 动画反馈 | 收藏(心形图标,开关式) | 🟡 中 |
+| **评论系统** | Response(也是文章形式)+ 内联评论 | ❌ 无 | 🟢 合理差异 |
+| **文章分享** | 多平台分享(Twitter/Facebook/LinkedIn/Link) | Web Share API + 复制链接 | 🟢 相当 |
+| **标注笔记** | 高亮 + 私人笔记 | 高亮 + 笔记(4 色可选) | 🟢 相当 |
+| **阅读列表** | 书签收藏到 Reading List | 收藏 + 历史记录 | 🟢 相当 |
+
+### 3.5 搜索与筛选
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **搜索入口** | 全局搜索(顶部放大镜) | 全局搜索(导航栏) | 🟢 相当 |
+| **搜索范围** | 全平台文章 + 作者 + 话题 + 出版物 | Feed 标题 + 文章标题/摘要 | 🟡 中 |
+| **筛选维度** | 话题、人物、出版物、时间 | 日期、Feed、已读状态、收藏 | 🟢 相当 |
+| **搜索建议** | 热门搜索 + 历史搜索 + 实时补全 | ❌ 无建议 | 🟡 中 |
+| **搜索结果排序** | 相关性 + 时间 + 热度 | 按时间排列 | 🟡 中 |
+
+### 3.6 个性化与设置
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **主题切换** | 暗色模式 | 亮/暗/跟随系统 三模式 | 🟢 RSS 更优 |
+| **多语言** | 内容多语言(自动检测) | UI 双语 (中/英) + AI 翻译 | 🟢 RSS 更优 |
+| **通知管理** | 邮件摘要 + 应用内通知 + 自定义频率 | 新文章通知(基础) | 🟡 中 |
+| **数据管理** | 导出数据(GDPR 合规) | OPML 导入/导出 + 本地数据 | 🟢 RSS 更优 |
+| **快捷键** | 有限的快捷键支持 | 计划中 (ROADMAP v1.1) | 🟡 中 |
+
+### 3.7 移动端体验
+
+| 环节 | Medium | RSS Reader | 差距 |
+|------|--------|------------|------|
+| **手势操作** | 左右滑动返回/前进 | 基础触摸操作 | 🟡 中 |
+| **底部导航** | ✅ 底部 Tab 栏 (Home/Search/Write/Notifications/Profile) | ✅ 底部 ActionBar + Sheet 导航 | 🟢 相当 |
+| **下拉刷新** | ✅ 原生下拉刷新 | ❌ 点击刷新按钮 | 🟡 中 |
+| **离线支持** | 有限(缓存已读文章) | ✅ 完整离线优先架构 | 🟢 RSS 更优 |
+| **PWA 安装** | ❌ 仅依赖 App Store 应用 | ✅ 完整 PWA 支持 | 🟢 RSS 更优 |
+
+---
+
+## 4. 功能项详细对比
+
+### 4.1 完整功能矩阵
+
+| 功能类别 | 功能项 | Medium | RSS Reader | 备注 |
+|---------|--------|--------|------------|------|
+| **内容获取** | 多源订阅 | ❌ 仅平台内 | ✅ RSS/Atom | RSS 优势 |
+| | OPML 导入/导出 | ❌ | ✅ | RSS 优势 |
+| | Feed 自动发现 | N/A | ❌ (计划 v1.2) | 可借鉴 |
+| | 热门推荐源 | ✅ | ❌ | **Gap** |
+| | 邮件转 RSS | ❌ | ❌ (计划 v2.0) | 双方均无 |
+| **阅读体验** | 排版系统 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | 可提升 |
+| | 阅读进度条 | ✅ | ❌ | **Gap** |
+| | 预计阅读时长 | ✅ | ❌ (计划 v1.1) | 已规划 |
+| | 文章目录 (TOC) | ✅ | ❌ | **Gap** |
+| | 代码语法高亮 | ✅ | ❌ | **Gap** |
+| | 图片灯箱放大 | ✅ | ❌ | **Gap** |
+| | 沉浸式阅读 | ✅ (无干扰模式) | ❌ | **Gap** |
+| | 字体/字号自定义 | ❌ | ❌ | 双方均无 |
+| | 全文提取 | 平台原生 | ✅ Readability | RSS 优势 |
+| **文章管理** | 收藏/书签 | ✅ | ✅ | 相当 |
+| | 阅读历史 | ✅ | ✅ | 相当 |
+| | 标注/高亮 | ✅ | ✅ (4 色) | 相当 |
+| | 标注导出 | ❌ | ❌ | **Gap** |
+| | 阅读列表管理 | ✅ (多列表) | ✅ (单收藏夹) | 可提升 |
+| | 批量已读 | ❌ | ❌ | **Gap** |
+| **搜索发现** | 全文搜索 | ✅ | ✅ | 相当 |
+| | 高级筛选 | ✅ | ✅ | 相当 |
+| | 搜索建议 | ✅ | ❌ | **Gap** |
+| | 相关推荐 | ✅ | ❌ | **Gap** |
+| | 话题/标签浏览 | ✅ | ❌ | **Gap** |
+| **社交互动** | 点赞/Clap | ✅ | ❌ (仅收藏) | 定位差异 |
+| | 评论 | ✅ | ❌ | 定位差异 |
+| | 分享 | ✅ | ✅ | 相当 |
+| | 关注作者 | ✅ | ❌ | 定位差异 |
+| **个性化** | 主题切换 | ✅ 暗色模式 | ✅ 三模式 | RSS 更优 |
+| | 多语言界面 | 有限 | ✅ 中/英 | RSS 更优 |
+| | AI 翻译 | ❌ | ✅ 流式翻译 | RSS 优势 |
+| | AI 摘要 | ❌ | ✅ 流式摘要 | RSS 优势 |
+| | 自定义刷新间隔 | N/A | ✅ 每 Feed 可设 | RSS 优势 |
+| **技术能力** | 离线阅读 | 有限 | ✅ 完整 | RSS 优势 |
+| | PWA | ❌ | ✅ | RSS 优势 |
+| | 后台同步 | N/A | ✅ Service Worker | RSS 优势 |
+| | 键盘快捷键 | 有限 | ❌ (计划 v1.1) | 已规划 |
+| | Podcast 播放 | ❌ | ✅ (内置播放器) | RSS 优势 |
+| **数据管理** | 数据导出 | ✅ GDPR 合规 | ✅ OPML | 相当 |
+| | 跨设备同步 | ✅ 云同步 | ❌ (计划 v1.3) | **Gap** |
+| | 本地优先 | ❌ | ✅ | RSS 优势 |
+
+### 4.2 RSS Reader 独特优势
+
+1. **去中心化**:用户完全控制内容来源,不受算法过滤
+2. **离线优先**:IndexedDB + Service Worker 实现完整离线能力
+3. **AI 集成**:流式翻译与摘要,提升跨语言阅读效率
+4. **隐私保护**:所有数据存储在本地,无追踪、无广告
+5. **Podcast 支持**:内置播放器支持音频内容
+6. **PWA 特性**:可安装到桌面/手机,接近原生体验
+7. **OPML 兼容**:标准数据格式,无供应商锁定
+
+### 4.3 RSS Reader 主要差距
+
+1. **阅读体验精细度**:排版、进度条、目录导航等阅读辅助功能缺失
+2. **新用户引导**:无推荐源、无引导流程,上手门槛高
+3. **内容发现能力**:无推荐、无相关文章、无标签浏览
+4. **阅读效率工具**:无阅读进度、无阅读时长估算、无批量操作
+5. **视觉细节打磨**:卡片信息密度不足、缺乏微交互动画
+
+---
+
+## 5. 差距总结与优先级矩阵
+
+### 5.1 优化项优先级评估
+
+| 优化项 | 用户价值 | 开发难度 | 竞品差距 | 优先级 |
+|--------|---------|---------|---------|--------|
+| 阅读进度条 | ⭐⭐⭐⭐ | ⭐ (低) | 🔴 大 | **P0** |
+| 预计阅读时长 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P0** |
+| 文章目录 (TOC) | ⭐⭐⭐⭐ | ⭐⭐ (中) | 🔴 大 | **P0** |
+| 推荐订阅源 | ⭐⭐⭐⭐⭐ | ⭐⭐ (中) | 🔴 大 | **P0** |
+| 排版升级 | ⭐⭐⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P1** |
+| 代码语法高亮 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P1** |
+| 图片灯箱 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P1** |
+| 键盘快捷键 | ⭐⭐⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P1** |
+| 下拉刷新 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P1** |
+| 搜索建议 | ⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P2** |
+| 无限滚动 | ⭐⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P2** |
+| 批量标记已读 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P1** |
+| 沉浸式阅读 | ⭐⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P2** |
+| 多阅读列表 | ⭐⭐ | ⭐⭐ (中) | 🟡 中 | **P2** |
+| 标注导出 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P2** |
+| 字体/字号自定义 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P2** |
+| 文章卡片信息增强 | ⭐⭐⭐ | ⭐ (低) | 🟡 中 | **P1** |
+| 新用户引导流程 | ⭐⭐⭐⭐ | ⭐⭐⭐ (高) | 🔴 大 | **P1** |
+
+---
+
+## 6. 优化建议
+
+### 6.1 阅读体验升级 (最高优先级)
+
+#### 📊 建议 1:阅读进度条
+
+**参考 Medium**:顶部细绿色进度条,随滚动显示阅读百分比。
+
+**实现方案**:
+```
+// 在 ArticleDetailPage 添加一个固定定位的进度条
+// 监听 scroll 事件计算 scrollTop / (scrollHeight - clientHeight)
+// 使用 CSS transform: scaleX() 实现平滑动画
+```
+
+**验收标准**:
+- 固定在页面顶部,高度 3px
+- 颜色跟随主题(亮色模式绿色,暗色模式蓝色)
+- 平滑动画(使用 requestAnimationFrame)
+- 阅读完成时保持 100% 状态
+- 性能:不影响滚动流畅度(使用 passive event listener)
+
+**预估工时**:0.5 天
+
+---
+
+#### ⏱ 建议 2:预计阅读时长
+
+**参考 Medium**:文章标题下方显示 "5 min read",基于字数计算。
+
+**实现方案**:
+- 中文按 400 字/分钟,英文按 200 词/分钟
+- 混合内容自动检测语言比例
+- 最小值显示 "1 min read" / "不到 1 分钟"
+
+**验收标准**:
+- 显示在文章标题和发布日期之间
+- 使用时钟图标 + 文字
+- 支持中英文自动切换
+- 不影响文章加载性能
+
+**预估工时**:0.5 天
+
+---
+
+#### 📑 建议 3:文章目录 (Table of Contents)
+
+**参考 Medium**:长文自动生成右侧浮动目录,当前阅读位置高亮。
+
+**实现方案**:
+- 解析文章 HTML 中的 h1-h3 标签生成目录树
+- 桌面端:右侧固定浮动面板
+- 移动端:顶部可收起的目录抽屉
+- 使用 IntersectionObserver 追踪当前阅读位置
+
+**验收标准**:
+- 仅当文章包含 ≥ 3 个标题时显示
+- 点击目录项平滑滚动到对应位置
+- 当前阅读位置的目录项高亮
+- 桌面端:固定在右侧,不遮挡正文
+- 移动端:浮动按钮展开/收起
+- 目录项超长时省略号截断
+
+**预估工时**:2 天
+
+---
+
+#### 🎨 建议 4:排版系统升级
+
+**参考 Medium**:精心调校的字体、行距、段距组合。
+
+**优化内容**:
+
+| 属性 | 当前值 | 建议值 | 理由 |
+|------|--------|--------|------|
+| 正文字体 | 系统默认 | 思源宋体/Georgia + 系统后备 | 提升中英文阅读舒适度 |
+| 正文字号 | Tailwind 默认 | 18px (桌面) / 16px (移动) | Medium 标准 |
+| 行高 | Tailwind prose 默认 | 1.7 (中文) / 1.58 (英文) | 匹配中文阅读习惯 |
+| 段间距 | Tailwind 默认 | 1.5em | 段落区分度不足 |
+| 最大行宽 | 48rem (768px) | 42rem (672px) | 更接近最优阅读列宽 |
+| 标题样式 | Tailwind prose | 加粗+更大尺寸+底部留白 | 视觉层次感 |
+
+**预估工时**:1 天
+
+---
+
+### 6.2 新用户引导优化
+
+#### 🌟 建议 5:推荐订阅源 + 快速上手
+
+**参考 Medium**:注册后选择兴趣话题,立即获得个性化内容。
+
+**实现方案**:
+
+**第一阶段:预置推荐源(低成本)**
+- 内置一份按分类整理的精选 Feed 列表(JSON 配置文件)
+- 涵盖科技、设计、编程、商业、生活等 6-8 个分类
+- 每个分类 3-5 个高质量 RSS 源
+- 用户首次打开时展示"快速订阅"引导卡片
+
+**第二阶段:引导流程**
+- 步骤 1:欢迎页面(介绍 RSS Reader 的核心价值)
+- 步骤 2:选择感兴趣的分类(复选框)
+- 步骤 3:一键订阅选中分类的推荐源
+- 步骤 4:进入主界面,自动触发首次刷新
+
+**验收标准**:
+- 仅在首次使用时展示引导流程
+- 用户可跳过引导直接进入主界面
+- 推荐源列表可通过配置文件更新
+- 选中即订阅,无需手动输入 URL
+- 完成引导后标记 `onboardingComplete` flag
+
+**预估工时**:3 天
+
+---
+
+#### 📰 建议 6:文章卡片信息增强
+
+**参考 Medium**:丰富的卡片信息(配图、作者头像、阅读时长、互动数据)。
+
+**优化内容**:
+- 在文章列表卡片中增加:缩略图(如有)、预计阅读时长、摘要预览(2 行截断)
+- 未读文章加粗标题 / 左侧蓝色竖线标记
+- 收藏文章显示心形角标
+- 卡片 hover 效果:微上浮 + 阴影加深
+
+**预估工时**:1.5 天
+
+---
+
+### 6.3 阅读效率提升
+
+#### ⌨️ 建议 7:键盘快捷键 (已在 ROADMAP)
+
+**补充建议**(参考 Medium 交互):
+- 增加 `s` 键保存/取消收藏(对标 Medium 的 Save)
+- 增加 `h` 键高亮选中文字
+- 增加 `n/p` 或 `←/→` 在文章间导航
+- 快捷键 overlay 使用模态对话框展示,分组展示(导航/文章/操作)
+
+---
+
+#### 📌 建议 8:批量操作
+
+**问题**:当前逐篇标记已读,效率低下。
+
+**优化**:
+- "全部标记已读" 按钮(Feed 级别 + 分类级别)
+- 长按/复选进入多选模式,支持批量收藏/已读/删除
+- 确认对话框防止误操作
+
+**预估工时**:1.5 天
+
+---
+
+#### 🔄 建议 9:下拉刷新 (移动端)
+
+**参考 Medium**:原生下拉刷新体验。
+
+**实现方案**:
+- 监听 `touchstart` → `touchmove` → `touchend` 事件链
+- 下拉超过阈值 (60px) 触发刷新
+- 加载动画(旋转图标 / 进度指示)
+- 仅在列表顶部时激活
+
+**预估工时**:1 天
+
+---
+
+### 6.4 内容展示增强
+
+#### 💡 建议 10:代码语法高亮
+
+**实现方案**:
+- 集成 `highlight.js` 或 `prism.js` (推荐 highlight.js,体积更小)
+- 自动检测代码语言
+- 添加 "复制代码" 按钮
+- 适配暗色/亮色主题
+
+**预估工时**:0.5 天
+
+---
+
+#### 🖼 建议 11:图片灯箱
+
+**实现方案**:
+- 点击文章内图片 → 全屏预览
+- 支持左右滑动切换同文章内的图片
+- 手势缩放(移动端)
+- ESC / 点击背景关闭
+- 使用轻量级库如 `medium-zoom` (仅 4KB)
+
+**预估工时**:0.5 天
+
+---
+
+#### 📖 建议 12:沉浸式阅读模式
+
+**参考 Medium**:无干扰、纯净的阅读界面。
+
+**实现方案**:
+- 进入沉浸模式时隐藏:顶部导航、侧边栏、底部操作栏
+- 仅保留文章正文 + 浮动返回按钮
+- 使用 `F11` 或专用按钮切换
+- 自动检测滚动方向:向下滚动隐藏所有 UI,向上滚动显示返回按钮
+
+**预估工时**:1 天
+
+---
+
+### 6.5 个性化增强
+
+#### 🔤 建议 13:字体与字号自定义
+
+**实现方案**:
+- 在设置中增加"阅读偏好"区域
+- 字号:小(14px) / 中(16px) / 大(18px) / 特大(20px)
+- 字体:系统默认 / 衬线体 / 无衬线体
+- 行间距:紧凑 / 适中 / 宽松
+- 设置存储在 localStorage,全局生效
+
+**预估工时**:1 天
+
+---
+
+#### 📚 建议 14:多阅读列表
+
+**参考 Medium**:用户可创建多个 Reading List。
+
+**实现方案**:
+- 允许用户创建命名的阅读列表(如"稍后阅读"、"技术文章"、"周末阅读")
+- 收藏时可选择加入哪个列表
+- 列表页面支持拖拽排序
+- 与现有收藏功能兼容(默认列表 = 收藏夹)
+
+**预估工时**:2 天
+
+---
+
+## 7. 迭代计划
+
+### 7.1 总览时间线
+
+```
+v1.1 阅读体验升级 ──────── 第 1-2 周 (高优先级)
+v1.2 效率与发现 ──────── 第 3-5 周 (中优先级)
+v1.3 精细化打磨 ──────── 第 6-8 周 (中优先级)
+v2.0 平台扩展 ──────── 第 9-12 周 (低优先级)
+```
+
+---
+
+### 7.2 v1.1 — 阅读体验升级 (第 1-2 周)
+
+**目标**:对标 Medium 的阅读体验核心功能,提升文章阅读满意度。
+
+| # | 功能 | 工时 | 周次 | 优先级 |
+|---|------|------|------|--------|
+| 1 | 阅读进度条 | 0.5d | W1 | P0 |
+| 2 | 预计阅读时长 | 0.5d | W1 | P0 |
+| 3 | 排版系统升级 | 1d | W1 | P1 |
+| 4 | 代码语法高亮 | 0.5d | W1 | P1 |
+| 5 | 图片灯箱 | 0.5d | W2 | P1 |
+| 6 | 文章卡片信息增强 | 1.5d | W2 | P1 |
+| 7 | 键盘快捷键 | 2d | W2 | P1 |
+
+**总工时**:6.5 人日
+**里程碑**:文章阅读体验达到 Medium 80% 水平
+
+**成功指标**:
+- 阅读页面停留时长提升 20%+
+- 用户报告阅读体验评分 ≥ 4.0/5.0
+
+---
+
+### 7.3 v1.2 — 效率与发现 (第 3-5 周)
+
+**目标**:降低使用门槛,提升日常使用效率。
+
+| # | 功能 | 工时 | 周次 | 优先级 |
+|---|------|------|------|--------|
+| 8 | 推荐订阅源 + 引导流程 | 3d | W3 | P0 |
+| 9 | 文章目录 (TOC) | 2d | W3-W4 | P0 |
+| 10 | 批量标记已读 | 1.5d | W4 | P1 |
+| 11 | 下拉刷新 (移动端) | 1d | W4 | P1 |
+| 12 | 搜索建议 + 历史 | 1.5d | W5 | P2 |
+| 13 | 标注导出 (JSON/Markdown) | 1d | W5 | P2 |
+
+**总工时**:10 人日
+**里程碑**:新用户首次使用体验达到 Medium 70% 水平
+
+**成功指标**:
+- 新用户 7 日留存率提升 30%+
+- 平均订阅 Feed 数从 X → X+3
+
+---
+
+### 7.4 v1.3 — 精细化打磨 (第 6-8 周)
+
+**目标**:补齐个性化能力,提升高级用户满意度。
+
+| # | 功能 | 工时 | 周次 | 优先级 |
+|---|------|------|------|--------|
+| 14 | 沉浸式阅读模式 | 1d | W6 | P2 |
+| 15 | 字体/字号自定义 | 1d | W6 | P2 |
+| 16 | 多阅读列表 | 2d | W7 | P2 |
+| 17 | 无限滚动 / 虚拟列表 | 2d | W7-W8 | P2 |
+| 18 | 文章内锚点导航 | 0.5d | W8 | P2 |
+| 19 | 微交互动画优化 | 1.5d | W8 | P2 |
+
+**总工时**:8 人日
+**里程碑**:产品精细度达到同类开源 RSS 阅读器前 10%
+
+**成功指标**:
+- 用户满意度评分 ≥ 4.5/5.0
+- GitHub Star 增长 50%+
+
+---
+
+### 7.5 v2.0 — 平台扩展 (第 9-12 周)
+
+**目标**:从阅读工具扩展为完整的信息管理平台。
+
+| # | 功能 | 工时 | 周次 | 优先级 |
+|---|------|------|------|--------|
+| 20 | 浏览器扩展 (Chrome + Firefox) | 5d | W9-W10 | 中 |
+| 21 | 跨设备同步 (可选后端) | 5d | W10-W11 | 中 |
+| 22 | Newsletter 集成 | 3d | W11-W12 | 低 |
+| 23 | 高级统计 (阅读量/时长) | 2d | W12 | 低 |
+
+**总工时**:15 人日
+**里程碑**:多端完整信息管理解决方案
+
+---
+
+### 7.6 里程碑汇总
+
+```
+Week 1-2: v1.1 阅读体验升级 │ 6.5 人日 │ P0/P1 功能
+Week 3-5: v1.2 效率与发现 │ 10 人日 │ P0/P1/P2 功能
+Week 6-8: v1.3 精细化打磨 │ 8 人日 │ P2 功能
+Week 9-12: v2.0 平台扩展 │ 15 人日 │ 中/低优先级
+ ─────────────────────┼───────────┤
+ 总计 │ 39.5 人日 │
+```
+
+---
+
+## 8. 附录:竞品功能速查表
+
+### 8.1 RSS Reader vs 主流阅读工具
+
+| 功能 | RSS Reader | Medium | Feedly | Inoreader | Reeder |
+|------|-----------|--------|--------|-----------|--------|
+| RSS/Atom 订阅 | ✅ | ❌ | ✅ | ✅ | ✅ |
+| 离线阅读 | ✅ 完整 | 有限 | Pro | Pro | ✅ |
+| AI 翻译/摘要 | ✅ | ❌ | ❌ | ❌ | ❌ |
+| 阅读进度条 | ❌ | ✅ | ❌ | ❌ | ❌ |
+| 文章目录 | ❌ | ✅ | ❌ | ❌ | ❌ |
+| 推荐源 | ❌ | ✅ | ✅ | ✅ | ❌ |
+| 标注/高亮 | ✅ | ✅ | ❌ | ✅ | ❌ |
+| 键盘快捷键 | ❌ | 有限 | ✅ | ✅ | ✅ |
+| Podcast | ✅ | ❌ | ✅ | ✅ | ❌ |
+| PWA | ✅ | ❌ | ✅ | ✅ | ❌ |
+| 跨设备同步 | ❌ | ✅ | ✅ | ✅ | ✅ (iCloud) |
+| 免费/开源 | ✅ | 免费+付费 | 免费+付费 | 免费+付费 | 付费 |
+| 本地优先 | ✅ | ❌ | ❌ | ❌ | ✅ |
+| 多语言 UI | ✅ | 有限 | ✅ | ✅ | ✅ |
+
+### 8.2 RSS Reader 竞争定位
+
+**核心竞争力**:
+1. 🏆 **唯一同时拥有"AI 集成 + 离线优先 + 开源免费"的 RSS 阅读器**
+2. 🏆 **完整 PWA 支持,无需应用商店即可安装**
+3. 🏆 **本地优先架构,数据完全由用户掌控**
+
+**需补齐的短板**(按影响排序):
+1. 阅读体验精细度(进度条、TOC、排版)
+2. 新用户引导(推荐源、引导流程)
+3. 效率工具(快捷键、批量操作)
+4. 跨设备能力(同步、浏览器扩展)
+
+---
+
+## 总结
+
+RSS Reader 已经是一个功能完善、技术领先的 RSS 阅读工具。相比 Medium,其核心差距不在功能数量,而在**阅读体验的精细度**和**新用户上手成本**。
+
+建议遵循"**体验优先、效率驱动**"的迭代策略:
+
+1. **v1.1 (W1-W2)**:先补齐阅读进度条、阅读时长、排版等"感知差距最大"的体验项
+2. **v1.2 (W3-W5)**:通过推荐源和引导流程降低使用门槛,同时增加 TOC 和批量操作提升效率
+3. **v1.3 (W6-W8)**:沉浸式阅读、字体自定义等精细化功能,提升高级用户满意度
+4. **v2.0 (W9-W12)**:浏览器扩展和跨设备同步,向完整信息管理平台演进
+
+**每个迭代完成后进行用户反馈收集和数据分析,根据实际数据调整后续迭代优先级。**
+
+---
+
+*文档版本: v1.0 | 最后更新: 2026-03-04 | 维护者: Product Team*
diff --git a/specs/002-reader-experience/plan.md b/specs/002-reader-experience/plan.md
new file mode 100644
index 0000000..fab7050
--- /dev/null
+++ b/specs/002-reader-experience/plan.md
@@ -0,0 +1,59 @@
+# Implementation Plan: v1.1 Reader Experience
+
+**Branch**: `002-reader-experience` | **Date**: 2026-03-05 | **Spec**: [spec.md](./spec.md)
+
+## Summary
+
+Upgrade article reading experience to close the gap with Medium identified in the competitive analysis. Six user stories covering: reading progress bar, CJK-aware reading time, typography optimization, code syntax highlighting, image lightbox, and enhanced article cards. All changes are front-end only with no database schema modifications.
+
+## Technical Context
+
+**Language/Version**: TypeScript 5.7 (strict mode)
+**Primary Dependencies**: React 18.3, Vite 7.3, Tailwind CSS 4.1, Zustand 4.5
+**Storage**: IndexedDB (existing, no changes)
+**Testing**: Vitest 4.0 (unit), Playwright 1.48 (e2e)
+**Target Platform**: PWA (Chrome/Firefox/Safari, Android, iOS)
+**Performance Goals**: 60fps scroll tracking, < 5ms reading time calculation
+**Constraints**: No new CSS files (Constitution VI), no new Zustand stores
+
+## Constitution Check
+
+- [x] **Principle I (PWA Architecture)**: All features work offline with cached articles
+- [x] **Principle II (Test-First)**: Each user story includes unit tests; ≥ 90% coverage target
+- [x] **Principle III (Responsive Design)**: Typography adapts to mobile/tablet/desktop breakpoints
+- [x] **Principle IV (Modern Tech)**: Uses existing TypeScript 5.7 + React 18 stack
+- [x] **Principle V (Observability)**: No new logging needed (UI-only changes)
+- [x] **Principle VI (Styling)**: All CSS in globals.css, no new CSS files
+- [x] **Principle VII (Routing)**: No route changes required
+- [x] **Principle VIII (Formatting)**: npm run format after all changes
+
+## Architecture Decisions
+
+1. **No database changes** — all new state is transient (progress, lightbox) or derived (reading time)
+2. **No new CSS files** — all style enhancements go into src/styles/globals.css per Constitution VI
+3. **No new dependencies for lightbox** — built with existing React + Lucide icons
+4. **Reading time utility enhanced in-place** — maintains backward compatibility
+5. **Code copy button** — uses native Clipboard API with execCommand fallback
+
+## Project Structure
+
+### New Files
+```
+src/hooks/useReadingProgress.ts # Scroll tracking hook
+src/hooks/useImageLightbox.ts # Lightbox state management hook
+src/components/ArticleView/ReadingProgressBar.tsx # Progress bar component
+src/components/ArticleView/CodeBlockEnhancer.tsx # Code block copy button
+src/components/ArticleView/ImageLightbox.tsx # Lightbox overlay component
+tests/unit/useReadingProgress.test.ts # Progress hook tests
+tests/unit/useImageLightbox.test.ts # Lightbox hook tests
+tests/unit/codeBlockCopy.test.ts # Code copy tests
+```
+
+### Modified Files
+```
+src/utils/readingTime.ts # Add CJK-aware calculation
+src/styles/globals.css # Typography enhancements
+src/pages/ArticleDetailPage.tsx # Integrate all features
+src/components/ArticleList/ArticleItem.tsx # Enhanced cards
+tests/unit/readingTime.test.ts # Additional CJK tests
+```
diff --git a/specs/002-reader-experience/spec.md b/specs/002-reader-experience/spec.md
new file mode 100644
index 0000000..916679e
--- /dev/null
+++ b/specs/002-reader-experience/spec.md
@@ -0,0 +1,165 @@
+# Feature Specification: v1.1 Reader Experience
+
+**Feature Branch**: `002-reader-experience`
+**Created**: 2026-03-05
+**Status**: Draft
+**Input**: User description: "v1.1 Reader Experience — 基于竞品 Medium 的对比分析,升级文章阅读体验。包含阅读进度条、预计阅读时长、排版优化、代码高亮、图片灯箱、文章卡片信息增强等功能。"
+
+**Note on Scope**: All user stories align with core features FR-003 (Read RSS Content) and secondary features FR-006 (Theme & Appearance). Competitive gap analysis in [docs/medium-comparison-report.md](../../docs/medium-comparison-report.md).
+
+## User Scenarios & Testing *(mandatory)*
+
+### User Story 1 - Reading Progress Bar (Priority: P1) - FR-003
+
+A user reading a long article sees a thin progress bar fixed at the top of the viewport. As they scroll through the article, the bar fills proportionally (0%–100%), providing continuous visual feedback on how much of the article remains.
+
+**Why this priority**: Reading progress is the highest-impact, lowest-effort improvement identified in the Medium comparison. It addresses the #1 reading experience gap.
+
+**Independent Test**: Open any article with scrollable content. Verify bar fills from 0% to 100% proportionally. Short articles (single viewport) show no bar.
+
+**Acceptance Scenarios**:
+
+1. **Given** user opens a long article, **When** the page loads, **Then** a 3px progress bar appears fixed at the very top of the page at 0%
+2. **Given** user scrolls to the midpoint, **When** 50% of content is scrolled, **Then** the bar fills to approximately 50%
+3. **Given** user scrolls to the bottom, **When** article is fully visible, **Then** the bar reaches 100% and stays there
+4. **Given** the article fits within a single viewport, **When** the page loads, **Then** no progress bar is shown
+
+---
+
+### User Story 2 - Reading Time Estimate with CJK Awareness (Priority: P1) - FR-003
+
+The article detail header displays an estimated reading time (e.g., "3 min read" / "3 分钟阅读"). The calculation uses 200 WPM for Latin text and 400 CPM for CJK characters, with bilingual content weighted by proportion.
+
+**Why this priority**: Already planned in ROADMAP v1.1 (#1). Quick win that helps users decide whether to read now or save for later.
+
+**Independent Test**: Open English and Chinese articles of known length; verify displayed times match expected ranges.
+
+**Acceptance Scenarios**:
+
+1. **Given** a 1000-word English article, **When** user opens it, **Then** header shows "5 min read"
+2. **Given** a 2000-character Chinese article, **When** user opens it, **Then** header shows "5 分钟阅读"
+3. **Given** a mixed English/Chinese article, **When** user opens it, **Then** reading time is calculated using weighted average of both speeds
+4. **Given** a very short article (< 200 words), **When** user opens it, **Then** header shows "1 min read" (minimum)
+
+---
+
+### User Story 3 - Typography & Readability Upgrade (Priority: P1) - FR-003, FR-006
+
+Article body typography is refined for optimal readability: 18px base font on desktop (16px mobile), 42rem max content width for optimal line length, enhanced heading hierarchy (h1–h4), and wider line spacing for CJK content.
+
+**Why this priority**: Typography quality is the most fundamental reading experience factor. Medium's typographic excellence is its defining feature.
+
+**Independent Test**: Open articles on desktop and mobile viewports; verify line width, text size, heading hierarchy, and paragraph spacing.
+
+**Acceptance Scenarios**:
+
+1. **Given** a desktop viewport (≥768px), **When** user reads an article, **Then** body text is 18px with max-width 42rem
+2. **Given** a mobile viewport (<768px), **When** user reads an article, **Then** body text is 16px with full-width layout
+3. **Given** a CJK-dominant article, **When** the page renders, **Then** line-height increases to 2.0 for improved readability
+4. **Given** an article with multiple heading levels, **When** the page renders, **Then** h1 > h2 > h3 > h4 follow a clear visual hierarchy
+
+---
+
+### User Story 4 - Code Syntax Highlighting (Priority: P2) - FR-003
+
+Code blocks (`
`) in article content are automatically syntax-highlighted with language auto-detection. A copy-to-clipboard button appears on each code block. Highlighting themes adapt to light/dark mode.
+
+**Why this priority**: Important for tech-focused RSS feeds but not essential for all users. Adds significant value for developer audience.
+
+**Independent Test**: Open an article with code blocks; verify syntax colouring, copy button functionality, and theme adaptation.
+
+**Acceptance Scenarios**:
+
+1. **Given** an article with a JavaScript code block, **When** the page renders, **Then** the code is syntax-highlighted with appropriate colours
+2. **Given** any code block, **When** user clicks the copy button, **Then** code text is copied to clipboard and button shows "Copied!" feedback for 2 seconds
+3. **Given** user toggles dark mode, **When** viewing highlighted code, **Then** the highlighting theme switches accordingly
+
+---
+
+### User Story 5 - Image Lightbox (Priority: P2) - FR-003
+
+Users can click on any image in an article to view it in a full-screen lightbox overlay. The lightbox supports navigation between images, close via ESC or backdrop click, and basic zoom on touch devices.
+
+**Why this priority**: Enhances media-rich article experience but not critical for text-focused reading.
+
+**Independent Test**: Open an article with images; click an image; verify lightbox opens with correct image, navigation works, ESC closes.
+
+**Acceptance Scenarios**:
+
+1. **Given** an article with images, **When** user clicks an image, **Then** a full-screen overlay opens showing the image at full resolution
+2. **Given** the lightbox is open with multiple images, **When** user clicks next/previous arrows, **Then** the next/previous image displays
+3. **Given** the lightbox is open, **When** user presses ESC or clicks the backdrop, **Then** the lightbox closes
+
+---
+
+### User Story 6 - Enhanced Article Cards (Priority: P2) - FR-003
+
+Article list cards are enriched with reading time estimate, favourite indicator (filled heart), and improved unread styling (bold title + subtle background tint).
+
+**Why this priority**: Improves information density and scannability but relies on reading time utility from US2.
+
+**Independent Test**: View feed list; verify cards show reading time, favourite hearts, and clear unread indicators.
+
+**Acceptance Scenarios**:
+
+1. **Given** a feed list with articles, **When** user views the list, **Then** each card shows reading time estimate
+2. **Given** a favourited article, **When** user views the list, **Then** the card shows a filled heart icon
+3. **Given** an unread article, **When** user views the list, **Then** the card has a bold title and subtle background tint
+
+---
+
+### Edge Cases
+
+- What happens when article content is empty or only contains images? → Reading time shows "1 min read" minimum
+- What happens when a code block has no language class? → Falls back to plain text display without highlighting
+- What happens when an article has no images? → No lightbox functionality, no visual change
+- What happens when the progress bar is on a very short article? → Bar is hidden (isFullyVisible = true)
+- What happens when CJK and Latin text are equally mixed (50/50)? → Weighted average of both reading speeds
+- What happens on extremely slow scroll? → Progress bar updates smoothly via requestAnimationFrame
+- What happens if clipboard API is not available? → Copy button falls back to document.execCommand('copy')
+- What happens with broken/missing images in lightbox? → Shows fallback placeholder
+
+## Requirements *(mandatory)*
+
+### Functional Requirements
+
+- **REQ-001**: System MUST display a reading progress bar that tracks scroll position (0%–100%) on the article detail page
+- **REQ-002**: Progress bar MUST be fixed at the top of the viewport, 3px height, using theme-aware primary colour
+- **REQ-003**: Progress bar MUST be hidden when article fits within a single viewport
+- **REQ-004**: Progress bar MUST use requestAnimationFrame and passive scroll listeners for performance
+- **REQ-005**: System MUST calculate reading time using 200 WPM for Latin text and 400 CPM for CJK characters
+- **REQ-006**: System MUST detect CJK character ratio to determine dominant language for display format
+- **REQ-007**: Reading time MUST be displayed in article detail header alongside author and date
+- **REQ-008**: Minimum displayed reading time MUST be 1 minute
+- **REQ-009**: Article content MUST use 18px base font size on desktop and 16px on mobile
+- **REQ-010**: Article content MUST have a max-width of 42rem for optimal line length
+- **REQ-011**: CJK-dominant articles MUST use increased line-height (2.0) for readability
+- **REQ-012**: Headings MUST follow clear visual hierarchy: h1 (2rem) > h2 (1.75rem) > h3 (1.5rem) > h4 (1.25rem)
+- **REQ-013**: Code blocks MUST be syntax-highlighted with auto-detected language
+- **REQ-014**: Each code block MUST include a copy-to-clipboard button
+- **REQ-015**: Code highlighting MUST adapt to light/dark theme
+- **REQ-016**: Clicking an article image MUST open a full-screen lightbox overlay
+- **REQ-017**: Lightbox MUST support navigation between images in the same article
+- **REQ-018**: Lightbox MUST close via ESC key, backdrop click, or close button
+- **REQ-019**: Article cards MUST show estimated reading time
+- **REQ-020**: Article cards MUST show favourite indicator (filled heart) when applicable
+- **REQ-021**: Unread articles MUST have visually distinct styling (bold title)
+
+### Key Entities
+
+- **ReadingProgress**: Transient state — progress (0.0–1.0), isFullyVisible (boolean)
+- **ReadingTimeResult**: Derived value — minutes, cjkCharCount, wordCount, isCjkDominant
+- **LightboxState**: Transient state — isOpen, currentIndex, images array, zoom level
+
+## Success Criteria *(mandatory)*
+
+### Measurable Outcomes
+
+- **SC-001**: Progress bar renders at 60fps during scroll (no jank)
+- **SC-002**: Reading time calculation adds < 5ms to article load time
+- **SC-003**: Typography changes pass WCAG AA contrast requirements
+- **SC-004**: CJK reading time accuracy within ±20% of manual estimate
+- **SC-005**: Code highlighting loads lazily, adding 0ms to initial page load
+- **SC-006**: Image lightbox opens within 100ms of click
+- **SC-007**: All new code has ≥ 90% unit test coverage
+- **SC-008**: No regressions to existing 245 passing tests
diff --git a/specs/002-reader-experience/tasks.md b/specs/002-reader-experience/tasks.md
new file mode 100644
index 0000000..5d595b0
--- /dev/null
+++ b/specs/002-reader-experience/tasks.md
@@ -0,0 +1,130 @@
+# Tasks: v1.1 Reader Experience
+
+**Input**: Design documents from `/specs/002-reader-experience/`
+**Prerequisites**: plan.md ✅, spec.md ✅
+
+**Constitution Requirement - Test-First (MANDATORY)**: Per RSS Reader Constitution Principle II, EVERY feature implementation MUST follow TDD. Tests MUST be written FIRST and MUST FAIL before implementation begins. Minimum 90% code coverage required.
+
+**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
+
+## Format: `[ID] [P?] [Story] Description`
+
+- **[P]**: Can run in parallel (different files, no dependencies)
+- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
+
+## Path Conventions
+
+- **Source**: `src/` at repository root
+- **Tests**: `tests/` at repository root
+- Components in `src/components/ArticleView/` and `src/components/ArticleList/`
+- Hooks in `src/hooks/`
+- Utilities in `src/utils/`
+- Styles in `src/styles/globals.css` (Constitution VI — no new CSS files)
+- Pages in `src/pages/`
+
+---
+
+## Phase 1: Foundational (Blocking Prerequisites)
+
+**Purpose**: Enhance readingTime utility with CJK awareness — shared by US2 and US6
+
+- [ ] T001 [P] Add unit tests for CJK-aware calculateReadingTime (CJK detection, bilingual calculation, isCjkDominant flag) in tests/unit/readingTime.test.ts
+- [ ] T002 Enhance calculateReadingTime with CJK character counting, detectCjkRatio helper, and isCjkDominant detection in src/utils/readingTime.ts
+- [ ] T003 Update existing calculateReadingTime call sites to use enhanced return value in src/pages/ArticleDetailPage.tsx
+
+**Checkpoint**: `npx vitest --run tests/unit/readingTime.test.ts` passes. Build succeeds.
+
+---
+
+## Phase 2: User Story 1 — Reading Progress Bar (Priority: P1) 🎯 MVP
+
+**Goal**: Fixed 3px progress bar at top of article detail page tracking scroll position
+
+- [ ] T004 [P] [US1] Write unit tests for useReadingProgress hook in tests/unit/useReadingProgress.test.ts
+- [ ] T005 [US1] Implement useReadingProgress hook with rAF-throttled passive scroll listener in src/hooks/useReadingProgress.ts
+- [ ] T006 [US1] Create ReadingProgressBar component (fixed 3px bar, CSS scaleX, role="progressbar") in src/components/ArticleView/ReadingProgressBar.tsx
+- [ ] T007 [US1] Integrate ReadingProgressBar into ArticleDetailPage in src/pages/ArticleDetailPage.tsx
+
+**Checkpoint**: Open any article → progress bar tracks scroll position smoothly.
+
+---
+
+## Phase 3: User Story 2 — Reading Time Display (Priority: P1)
+
+**Goal**: CJK-aware reading time in article detail header
+
+- [ ] T008 [US2] Enhance reading time display in ArticleDetailPage to use CJK-aware calculation and conditionally apply CJK class in src/pages/ArticleDetailPage.tsx
+
+**Checkpoint**: Article detail header shows accurate reading time for English and CJK articles.
+
+---
+
+## Phase 4: User Story 3 — Typography Upgrade (Priority: P1)
+
+**Goal**: Optimal readability typography for article content
+
+- [ ] T009 [P] [US3] Enhance .article-content base typography: 1.125rem desktop, 1rem mobile, 42rem max-width, 1.25em paragraph spacing in src/styles/globals.css
+- [ ] T010 [P] [US3] Enhance heading hierarchy: h1 2rem, h2 1.75rem, h3 1.5rem, h4 1.25rem with improved margins in src/styles/globals.css
+- [ ] T011 [US3] Add .article-content-cjk class with line-height 2.0, pre position: relative, img cursor: pointer in src/styles/globals.css
+
+**Checkpoint**: Articles render with optimised typography. CJK articles get wider line spacing.
+
+---
+
+## Phase 5: User Story 4 — Code Syntax Highlighting (Priority: P2)
+
+**Goal**: Auto-highlight code blocks with copy button
+
+- [ ] T012 [P] [US4] Write unit tests for code block copy functionality in tests/unit/codeBlockCopy.test.ts
+- [ ] T013 [US4] Create CodeBlockEnhancer component with copy button for pre>code elements in src/components/ArticleView/CodeBlockEnhancer.tsx
+- [ ] T014 [US4] Integrate code block enhancement into ArticleDetailPage in src/pages/ArticleDetailPage.tsx
+
+**Checkpoint**: Code blocks in articles display copy buttons that work correctly.
+
+---
+
+## Phase 6: User Story 5 — Image Lightbox (Priority: P2)
+
+**Goal**: Full-screen image viewing by clicking article images
+
+- [ ] T015 [P] [US5] Write unit tests for useImageLightbox hook in tests/unit/useImageLightbox.test.ts
+- [ ] T016 [US5] Implement useImageLightbox hook in src/hooks/useImageLightbox.ts
+- [ ] T017 [US5] Create ImageLightbox component in src/components/ArticleView/ImageLightbox.tsx
+- [ ] T018 [US5] Integrate lightbox into ArticleDetailPage in src/pages/ArticleDetailPage.tsx
+
+**Checkpoint**: Article images are clickable, lightbox opens with full-screen view.
+
+---
+
+## Phase 7: User Story 6 — Enhanced Article Cards (Priority: P2)
+
+**Goal**: Richer article list cards with reading time and favourite indicator
+
+- [ ] T019 [US6] Enhance ArticleItem with reading time display, favourite heart icon, and improved unread styling in src/components/ArticleList/ArticleItem.tsx
+
+**Checkpoint**: Feed list shows enhanced cards with all metadata.
+
+---
+
+## Phase 8: Polish & Cross-Cutting
+
+- [ ] T020 Run `npm run format` for Prettier compliance (Constitution VIII)
+- [ ] T021 Run `npx vitest --run` to verify all tests pass (≥ 245 existing + new)
+- [ ] T022 Run `npx tsc --noEmit` to verify TypeScript compilation
+
+---
+
+## Dependencies & Execution Order
+
+```
+Phase 1: Foundational (readingTime utility) — BLOCKS all
+ │
+ ├── US1 (Phase 2): Progress Bar ──► Independent
+ ├── US2 (Phase 3): Reading Time ──► Independent
+ ├── US3 (Phase 4): Typography ──┬─► Independent
+ │ ├── US4 (Phase 5): Code Highlighting
+ │ └── US5 (Phase 6): Image Lightbox
+ └── US6 (Phase 7): Enhanced Cards ► Independent
+```
+
+**Key**: After Phase 1, US1/US2/US3/US6 can proceed in parallel. US4 and US5 depend on US3 CSS prep.
diff --git a/src/components/ArticleList/ArticleItem.tsx b/src/components/ArticleList/ArticleItem.tsx
index b975d4e..c1c1b5d 100644
--- a/src/components/ArticleList/ArticleItem.tsx
+++ b/src/components/ArticleList/ArticleItem.tsx
@@ -1,10 +1,14 @@
/**
* ArticleItem Component
- * Individual article list item with title, summary, date, and read status
+ * Individual article list item with title, summary, date, read status,
+ * reading time estimate, and favourite indicator.
*/
+import { useMemo } from 'react';
+import { Heart, Clock } from 'lucide-react';
import { Article } from '../../models/Feed';
import { useOfflineDetection } from '../../hooks/useOfflineDetection';
+import { calculateReadingTime, formatReadingTime } from '../../utils/readingTime';
interface ArticleItemProps {
article: Article;
@@ -20,9 +24,16 @@ export function ArticleItem({ article, onClick }: ArticleItemProps) {
? publishDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' })
: publishDate.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
+ const readingTime = useMemo(() => {
+ const content = article.content || article.summary || '';
+ if (!content) return null;
+ const result = calculateReadingTime(content);
+ return formatReadingTime(result.minutes);
+ }, [article.content, article.summary]);
+
return (