# Plan 33-01: Deep-Reading Dashboard Rendering

**Phase:** 33 — Deep-Reading Dashboard Rendering
**Goal:** Render status card, Pass 1 summary card, and AI Q&A history card in deep-reading mode.
**Depends on:** Phase 32 (mode detection provides `_currentPaperEntry` and `_renderDeepReadingMode()` entry point)
**Requirements:** DEEP-02, DEEP-03
**CONTEXT:** `.planning/phases/33-deep-reading-dashboard-rendering/33-CONTEXT.md`

## Tasks

### Task 1: Build deep-reading view container and read data

Add file reading helpers at the top of `_renderDeepReadingMode()`:

```javascript
_renderDeepReadingMode() {
    const entry = this._currentPaperEntry;
    const view = this._contentEl.createEl('div', { cls: 'paperforge-mode-deepreading' });
    
    // Read deep-reading.md content
    let deepReadingText = '';
    if (entry && entry.deep_reading_path) {
        const drFile = this.app.vault.getAbstractFileByPath(entry.deep_reading_path);
        if (drFile) {
            deepReadingText = await this.app.vault.read(drFile);
        }
    }
    
    // Read discussion.json
    let discussionData = null;
    if (entry && entry.ai_path) {
        const aiDir = entry.ai_path.replace(/^\[\[/, '').replace(/\]\]$/, '');
        const djPath = aiDir + '/discussion.json';
        const djFile = this.app.vault.getAbstractFileByPath(djPath);
        if (djFile) {
            try {
                const raw = await this.app.vault.read(djFile);
                discussionData = JSON.parse(raw);
            } catch (e) { /* file missing or parse error */ }
        }
    }
    
    // Render sections
    this._renderDeepStatusCard(view, entry);
    this._renderDeepPass1Card(view, deepReadingText);
    this._renderDeepQACard(view, discussionData);
}
```

Note: `_renderDeepReadingMode` needs to become async (or use Obsidian API promises).

### Task 2: Status card

```javascript
_renderDeepStatusCard(container, entry) {
    const card = container.createEl('div', { cls: 'paperforge-deepreading-card' });
    card.createEl('div', { cls: 'paperforge-deepreading-card-title', text: '📊 状态概览' });
    
    if (!entry) {
        card.createEl('div', { cls: 'paperforge-deepreading-empty', text: '暂无数据' });
        return;
    }
    
    const statusItems = [
        { label: 'Figure-Map', value: entry.figure_map ? '✅ 已生成' : '⏳ 待生成' },
        { label: 'OCR 状态', value: entry.ocr_status === 'done' ? '✅ 已完成' : '⏳ ' + (entry.ocr_status || '待处理') },
        { label: 'Pass 完成', value: getPassCompletion(entry) },
        { label: '健康状况', value: entry.health && entry.health.pdf_health === 'healthy' ? '✅ 正常' : '⚠️ 需关注' },
    ];
    
    for (const item of statusItems) {
        const row = card.createEl('div', { cls: 'paperforge-deepreading-status-row' });
        row.createEl('span', { cls: 'paperforge-deepreading-status-label', text: item.label });
        row.createEl('span', { cls: 'paperforge-deepreading-status-value', text: item.value });
    }
}
```

Helper for Pass completion:
```javascript
function getPassCompletion(entry) {
    const status = entry.deep_reading_status || 'pending';
    if (status === 'done') return '✅ 3/3 (已完成)';
    // Check deep-reading.md for specific pass markers
    return '⏳ 待完成';
}
```

### Task 3: Pass 1 summary card

```javascript
_renderDeepPass1Card(container, text) {
    const card = container.createEl('div', { cls: 'paperforge-deepreading-card' });
    card.createEl('div', { cls: 'paperforge-deepreading-card-title', text: '📝 Pass 1 总结' });
    
    if (!text || text.trim() === '') {
        card.createEl('div', { cls: 'paperforge-deepreading-empty', text: '暂无 Pass 1 总结' });
        return;
    }
    
    // D-04: Extract content after **一句话总览** marker
    const extracted = extractPass1Content(text);
    if (!extracted) {
        card.createEl('div', { cls: 'paperforge-deepreading-empty', text: '暂无 Pass 1 总结' });
        return;
    }
    
    // Render extracted content as markdown-like text
    const content = card.createEl('div', { cls: 'paperforge-deepreading-pass1-content' });
    const lines = extracted.split('\n').filter(l => l.trim());
    for (const line of lines) {
        if (line.startsWith('### ')) {
            content.createEl('h4', { cls: 'paperforge-deepreading-pass1-subheading', text: line.replace('### ', '') });
        } else if (line.startsWith('**') && line.endsWith('**')) {
            content.createEl('p', { cls: 'paperforge-deepreading-pass1-marker', text: line });
        } else if (line.trim()) {
            content.createEl('p', { cls: 'paperforge-deepreading-pass1-text', text: line });
        }
    }
}
```

Helper function:
```javascript
function extractPass1Content(text) {
    const markers = ['**一句话总览**', '## Pass 1', '**文章摘要**'];
    let content = '';
    for (const marker of markers) {
        const idx = text.indexOf(marker);
        if (idx !== -1) {
            // Find the next major break (next ** section heading or end)
            const after = idx + marker.length;
            const nextMarker = text.indexOf('**证据边界**', after) !== -1 ? text.indexOf('**证据边界**', after)
                         : text.indexOf('**Figure 导读**', after) !== -1 ? text.indexOf('**Figure 导读**', after)
                         : text.length;
            content = text.substring(after, nextMarker).trim();
            break;
        }
    }
    return content || null;
}
```

### Task 4: AI Q&A history card (collapsible sessions, dialog bubbles)

```javascript
_renderDeepQACard(container, data) {
    const card = container.createEl('div', { cls: 'paperforge-deepreading-card' });
    const header = card.createEl('div', { cls: 'paperforge-deepreading-card-header collapsible' });
    header.createEl('div', { cls: 'paperforge-deepreading-card-title', text: '💬 AI 问答记录' });
    
    // D-10: Default collapsed
    const body = card.createEl('div', { cls: 'paperforge-deepreading-card-body collapsed' });
    
    // Toggle on click
    header.addEventListener('click', () => {
        body.classList.toggle('collapsed');
        header.classList.toggle('expanded');
    });
    
    // D-12: Empty states
    if (!data || !data.sessions || data.sessions.length === 0) {
        body.createEl('div', { cls: 'paperforge-deepreading-empty', text: !data ? '暂无讨论记录' : '暂无问答内容' });
        return;
    }
    
    // D-08: Sessions-based grouping
    for (const session of data.sessions) {
        const sessionEl = body.createEl('div', { cls: 'paperforge-deepreading-session' });
        const sessionHeader = sessionEl.createEl('div', { cls: 'paperforge-deepreading-session-header' });
        sessionHeader.createEl('span', { text: session.model || 'AI' });
        sessionHeader.createEl('span', { cls: 'paperforge-deepreading-session-date', text: session.started || '' });
        
        // D-09: Dialog bubbles
        if (session.qa_pairs) {
            for (const qa of session.qa_pairs) {
                const qBubble = sessionEl.createEl('div', { cls: 'paperforge-deepreading-bubble question' });
                qBubble.createEl('div', { cls: 'bubble-label', text: '问题' });
                qBubble.createEl('div', { cls: 'bubble-text', text: qa.question });
                
                const aBubble = sessionEl.createEl('div', { cls: 'paperforge-deepreading-bubble answer' });
                aBubble.createEl('div', { cls: 'bubble-label', text: '解答' });
                aBubble.createEl('div', { cls: 'bubble-text', text: qa.answer });
            }
        }
    }
}
```

### Task 5: CSS additions

Add to `styles.css` under SECTION 33:

```css
/* ==========================================================================
   SECTION 33 — Deep-Reading Dashboard Mode
   ========================================================================== */
.paperforge-mode-deepreading {
    display: flex;
    flex-direction: column;
    gap: var(--size-4-4, 16px);
}

.paperforge-deepreading-card {
    background: var(--background-primary-alt);
    border-radius: var(--radius-m, 8px);
    padding: var(--size-4-4, 16px);
}

.paperforge-deepreading-card-title {
    font-weight: 600;
    font-size: var(--font-ui-medium);
    margin-bottom: var(--size-4-2, 8px);
}

.paperforge-deepreading-card-header.collapsible {
    cursor: pointer;
    user-select: none;
}

.paperforge-deepreading-card-body.collapsed {
    display: none;
}

.paperforge-deepreading-status-row {
    display: flex;
    justify-content: space-between;
    padding: var(--size-4-1, 4px) 0;
    border-bottom: 1px solid var(--background-modifier-border);
}

.paperforge-deepreading-status-label {
    color: var(--text-muted);
    font-size: var(--font-ui-small);
}

.paperforge-deepreading-status-value {
    font-size: var(--font-ui-small);
}

.paperforge-deepreading-pass1-content {
    line-height: 1.6;
}

.paperforge-deepreading-pass1-subheading {
    margin: var(--size-4-2, 8px) 0 var(--size-4-1, 4px);
    color: var(--text-accent);
}

.paperforge-deepreading-pass1-marker {
    font-weight: 600;
    color: var(--text-normal);
}

.paperforge-deepreading-pass1-text {
    color: var(--text-muted);
    margin: var(--size-4-1, 4px) 0;
}

/* Dialog bubbles */
.paperforge-deepreading-session {
    margin-bottom: var(--size-4-3, 12px);
}

.paperforge-deepreading-session-header {
    display: flex;
    justify-content: space-between;
    font-size: var(--font-ui-small);
    color: var(--text-faint);
    margin-bottom: var(--size-4-2, 8px);
}

.paperforge-deepreading-bubble {
    padding: var(--size-4-2, 8px) var(--size-4-3, 12px);
    border-radius: var(--radius-s, 6px);
    margin-bottom: var(--size-4-2, 8px);
    max-width: 90%;
}

.paperforge-deepreading-bubble.question {
    background: var(--interactive-accent);
    color: var(--text-on-accent);
    align-self: flex-start;
}

.paperforge-deepreading-bubble.answer {
    background: var(--background-secondary-alt);
    color: var(--text-normal);
    margin-left: auto;
}

.bubble-label {
    font-size: var(--font-smallest);
    opacity: 0.7;
    margin-bottom: 2px;
}

.bubble-text {
    font-size: var(--font-ui-small);
    line-height: 1.5;
}

.paperforge-deepreading-empty {
    color: var(--text-faint);
    font-size: var(--font-ui-small);
    padding: var(--size-4-2, 8px);
    text-align: center;
}
```

## Success Criteria

1. Opening deep-reading.md shows three cards: status overview, Pass 1 summary, AI Q&A.
2. Status card shows figure-map, OCR, Pass completion, health info from index entry.
3. Pass 1 summary shows `**一句话总览**` content with `###` sub-sections.
4. AI Q&A section is collapsed by default; clicking expands to session groups with dialog bubbles.
5. All 4 empty-state conditions show Chinese fallback text (never JS errors).
6. CSS is scoped under `.paperforge-mode-deepreading`.

## Rollback

```bash
git checkout -- paperforge/plugin/main.js paperforge/plugin/styles.css
```
