# Story 2.4: Export & Copy Actions

Status: review

<!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->

## Story

As a user,
I want to copy the text or save the post,
So that I can publish it on LinkedIn or save it for later.

## Acceptance Criteria

1. **Copy to Clipboard on Thumbs Up**
   - Given the user likes the draft
   - When they click "Thumbs Up" or "Copy"
   - Then the full Markdown text is copied to the clipboard
   - And a success toast/animation confirms the action

2. **Save Draft as Completed**
   - Given the draft is finalized
   - When the user saves it
   - Then it is marked as "Completed" in the local database
   - And the user is returned to the Home/History screen

## Tasks / Subtasks

- [x] Implement Clipboard Copy Functionality
  - [x] Create `copyToClipboard()` utility in `src/lib/utils/clipboard.ts`
  - [x] Support copying Markdown formatted text
  - [x] Handle clipboard API errors gracefully
  - [x] Add fallback for older browsers

- [x] Create Success Feedback Toast
  - [x] Create `CopySuccessToast.tsx` component in `src/components/features/feedback/`
  - [x] Show confetti or success animation on copy
  - [x] Auto-dismiss after 3 seconds
  - [x] Include haptic feedback on mobile devices
  - [x] Accessible: announce to screen readers

- [x] Extend DraftActions with Copy/Save
  - [x] Add "Copy" button variant (separate from Thumbs Up)
  - [x] Wire Thumbs Up to both copy AND save actions
  - [x] Add "Just Copy" option (copy without closing sheet)
  - [x] Add "Save & Close" action

- [x] Implement Draft Completion Logic
  - [x] Add `completeDraft(draftId: number)` action to ChatStore
  - [x] Update draft status from 'draft' to 'completed' in IndexedDB
  - [x] Clear `currentDraft` from store after completion
  - [x] Close DraftViewSheet after completion
  - [ ] Navigate to Home/History screen (deferred to Epic 3)

- [x] Implement DraftService Completion Method
  - [x] Add `markAsCompleted(draftId: string)` to `src/lib/db/draft-service.ts`
  - [x] Update DraftRecord status in IndexedDB
  - [x] Add `completedAt` timestamp
  - [x] Return updated draft record

- [ ] Create History Screen Navigation
  - [ ] Add navigation to Home/History after save
  - [ ] Ensure completed draft appears in history feed
  - [ ] Scroll to newly saved draft in history
  - [ ] Highlight the newly saved entry

- [x] Add Copy Accessibility Features
  - [x] Add `aria-label` to all copy buttons
  - [x] Announce "Copied to clipboard" to screen readers
  - [ ] Support keyboard shortcuts (Cmd+C / Ctrl+C) (deferred - enhancement)
  - [ ] Ensure focus management after copy action (deferred - enhancement)

- [x] Test Copy & Save End-to-End
  - [x] Unit test: clipboard.copyText() with Markdown (12 tests)
  - [x] Unit test: DraftService.markAsCompleted() updates status (3 tests)
  - [x] Integration test: Thumbs Up -> Copy -> Save flow (DraftViewSheet tests)
  - [x] Integration test: Copy button only (no save) (DraftViewSheet tests)
  - [x] Edge case: Clipboard permission denied (clipboard fallback tests)
  - [x] Edge case: Draft already marked as completed (DraftService tests)
  - [ ] Edge case: Copy with very long draft content (deferred - stress test)

- [ ] Test History Integration
  - [ ] Integration test: Completed draft appears in history feed (deferred to Epic 3)
  - [ ] Integration test: Copy action from history view (Epic 3)
  - [ ] Test: Multiple drafts saved in session (deferred to Epic 3)

## Dev Notes

### Architecture Compliance (CRITICAL)

**Logic Sandwich Pattern - DO NOT VIOLATE:**
- **UI Components** MUST NOT import `src/lib/db` or clipboard utilities directly
- All completion logic MUST go through `ChatService` layer
- ChatService then calls `DraftService` for database operations
- Components use Zustand store via atomic selectors only
- Services return plain objects, not Dexie observables

**State Management - Atomic Selectors Required:**
```typescript
// BAD - Causes unnecessary re-renders
const { currentDraft } = useChatStore();

// GOOD - Atomic selectors
const currentDraft = useChatStore(s => s.currentDraft);
const completeDraft = useChatStore(s => s.completeDraft);
```

**Local-First Data Boundary:**
- Completed drafts MUST be stored in IndexedDB
- Status change from 'draft' to 'completed' persists locally
- Clipboard operations are client-side only (no server interaction)
- Draft history is queryable from history view (Epic 3)

**Edge Runtime Constraint:**
- This story does NOT require Edge API calls (clipboard is client-side only)
- All operations happen in the browser for privacy and speed

### Architecture Implementation Details

**Issue Resolution (Review Fixes):**
- **Logic Sandwich Violation:** Fixed `ChatStore.completeDraft` to call `ChatService.approveDraft` instead of direct DB acton.
- **Missing Component:** Created `CopyButton.tsx` and refactored `DraftActions` to use it.
- **Redundancy:** Consolidated `approveDraft` and `completeDraft` in Store.

**Story Purpose:**
This story implements the **"Export & Completion"** flow - the final step where users copy their polished draft to clipboard and save it to their local history. This completes the core value loop: Vent -> Generate -> Refine -> Export.

**State Management Extensions:**
```typescript
// Add to ChatStore (src/lib/store/chat-store.ts)
interface ChatStore {
  // Existing state
  currentDraft: Draft | null;

  // New actions for this story
  completeDraft: (draftId: string) => Promise<void>;
  copyDraftToClipboard: (draftId: string) => Promise<void>;
  copyAndSaveDraft: (draftId: string) => Promise<void>;
}
```

**Completion Logic Flow:**
1. User views draft in DraftViewSheet (Story 2.2)
2. User taps **Thumbs Up** OR **Copy** button
3. **Thumbs Up path:**
   - Copy Markdown to clipboard
   - Show success toast with confetti
   - Mark draft as 'completed' in IndexedDB
   - Clear currentDraft from store
   - Close DraftViewSheet
   - Navigate to Home/History
   - Scroll to/highlight newly saved entry
4. **Copy Only path:**
   - Copy Markdown to clipboard
   - Show success toast
   - Keep sheet open (user can continue viewing)

**Clipboard Utility Pattern:**
```typescript
// src/lib/utils/clipboard.ts
export class ClipboardUtil {
  static async copyMarkdown(markdown: string): Promise<boolean> {
    try {
      await navigator.clipboard.writeText(markdown);
      return true;
    } catch (error) {
      // Fallback for older browsers
      return this.fallbackCopy(markdown);
    }
  }

  private static fallbackCopy(text: string): boolean {
    const textarea = document.createElement('textarea');
    textarea.value = text;
    document.body.appendChild(textarea);
    textarea.select();
    const success = document.execCommand('copy');
    document.body.removeChild(textarea);
    return success;
  }
}
```

**Draft Completion in Database:**
```typescript
// src/lib/db/draft-service.ts
export class DraftService {
  static async markAsCompleted(draftId: string): Promise<Draft> {
    await db.drafts.update(draftId, {
      status: 'completed',
      completedAt: Date.now()
    });
    return this.getDraftById(draftId);
  }
}
```

**Files to Create:**
- `src/lib/utils/clipboard.ts` - Clipboard utility with fallback
- `src/components/features/feedback/CopySuccessToast.tsx` - Success feedback
- `src/components/features/draft/CopyButton.tsx` - Standalone copy button

**Files to Modify:**
- `src/lib/store/chat-store.ts` - Add completion actions
- `src/lib/db/draft-service.ts` - Add markAsCompleted() method
- `src/services/chat-service.ts` - Add completion orchestration
- `src/components/features/draft/DraftActions.tsx` - Add Copy/Save buttons
- `src/app/(main)/page.tsx` - Navigate to history after save (optional scroll)

### UX Design Specifications

**From UX Design Document:**

**Completion Reward Pattern:**
- Thumbs Up triggers "You're done!" animation
- Confetti or haptic feedback provides dopamine hit
- Success toast confirms copy action
- Auto-navigation to history reinforces "saved to your journal"

**Visual Feedback - Success State:**
```mermaid
graph TD
    A[User Taps Thumbs Up] --> B[Copy to Clipboard]
    B --> C[Show Success Toast]
    C --> D[Confetti Animation]
    D --> E[Mark as Completed]
    E --> F[Close Sheet]
    F --> G[Navigate to History]
    G --> H[Highlight New Entry]
```

**Toast Design Specifications:**
- Position: Top-center or bottom-center (mobile)
- Duration: 3 seconds auto-dismiss
- Icon: Checkmark or clipboard icon
- Text: "Copied to clipboard!" or "Draft saved!"
- Animation: Fade in + slide up
- Confetti: Subtle particle burst on success

**Button Hierarchy:**
- **Primary (Thumbs Up):** Copy + Save + Close (complete action)
- **Secondary (Copy Only):** Copy to clipboard, keep sheet open
- **Tertiary (Close):** Dismiss without saving

**Tone and Emotion:**
- Success state should feel celebratory
- "You're done, great job!" messaging
- Reinforces the value of completing the ritual

**Micro-interactions:**
- Thumbs Up should have "spring" animation
- Haptic feedback on mobile (vibration)
- Smooth transition to history screen
- New entry in history has subtle highlight/fade-in

### Previous Story Intelligence (from Stories 2.1, 2.2, and 2.3)

**Patterns Established (must follow):**
- **Logic Sandwich Pattern:** UI -> Zustand -> Service -> DB (strictly enforced)
- **Atomic Selectors:** All state access uses `useChatStore(s => s.field)`
- **Draft Storage:** Drafts stored in IndexedDB via `drafts` table
- **DraftViewSheet:** Sheet component that responds to `currentDraft` state
- **Draft Status Flow:** 'draft' -> 'regenerated' -> 'completed'

**Key Files from Previous Stories:**
- `src/lib/db/draft-service.ts` - Draft CRUD operations (add completion method)
- `src/lib/store/chat-store.ts` - Has currentDraft, add completion actions
- `src/components/features/draft/DraftActions.tsx` - Thumbs Up/Down, add Copy/Save
- `src/components/features/draft/DraftViewSheet.tsx` - Sheet component
- `src/services/chat-service.ts` - Chat orchestration (add completion flow)

**Learnings to Apply:**
- Story 2.2 established DraftViewSheet auto-opens on currentDraft - clear it to close
- Story 2.3 established draft versioning - 'completed' status marks the final version
- Use same success animation pattern from Story 2.2 (shimmer -> reveal)
- Follow same error handling pattern (retry on clipboard failure)
- Story 2.1 established DraftRecord structure - add `completedAt` timestamp

**Draft Data Structure (extending from Story 2.1):**
```typescript
interface DraftRecord {
  id: string;
  sessionId: string;
  title: string;
  content: string;      // Markdown formatted
  tags: string[];
  createdAt: number;
  completedAt?: number; // NEW: Set when draft is marked as completed
  status: 'draft' | 'completed' | 'regenerated';
}
```

**Integration with Refinement (Story 2.3):**
- If user refined draft, the final version is marked as 'completed'
- Original draft(s) with status 'regenerated' remain in history
- Only the latest draft (the one user approved) gets 'completed' status
- History view (Epic 3) will show all versions, highlighting the completed one

### Clipboard Implementation Specifications

**Browser Clipboard API:**
```typescript
// Modern browsers (Chrome 66+, Firefox 63+, Safari 13.1+)
navigator.clipboard.writeText(markdown)
  .then(() => showSuccessToast())
  .catch(() => showFallbackMessage());
```

**Fallback for Older Browsers:**
```typescript
// Create hidden textarea, select, execCommand('copy')
// Remove textarea after copy
// Returns boolean success
```

**Clipboard Permissions:**
- Clipboard API requires user gesture (button click)
- No permissions needed for writeText() in active tab
- May fail in iframes or cross-origin contexts

**Accessibility for Copy:**
```typescript
<button
  onClick={handleCopy}
  aria-label="Copy draft to clipboard"
  className="..."
>
  <CopyIcon />
  <span className="sr-only">Copy</span>
</button>

// After copy, announce to screen readers
useEffect(() => {
  if (copied) {
    announceToScreenReader('Draft copied to clipboard');
  }
}, [copied]);
```

**Keyboard Shortcut Support:**
- Detect Cmd+C / Ctrl+C when draft is visible
- Show tooltip: "Press Cmd+C to copy"
- Prevent interference with browser default

### Testing Requirements

**Unit Tests:**
- `ClipboardUtil.copyMarkdown()` copies text correctly
- `ClipboardUtil.copyMarkdown()` handles errors gracefully
- `ClipboardUtil.fallbackCopy()` works for older browsers
- `DraftService.markAsCompleted()` updates status
- `DraftService.markAsCompleted()` sets completedAt timestamp
- `ChatStore.completeDraft()` clears currentDraft
- `ChatStore.copyDraftToClipboard()` calls ClipboardUtil

**Integration Tests:**
- Full completion flow: Thumbs Up -> Copy -> Save -> Navigate
- Copy only flow: Copy button -> Toast -> Sheet stays open
- Draft appears in history after completion
- Multiple drafts in session show all completed drafts
- Refinement + completion: Refined draft marked as completed

**Edge Cases:**
- Clipboard permission denied: Show error message
- Clipboard API unavailable: Use fallback method
- Draft already completed: Show message, don't duplicate
- Very long draft content: Should handle within clipboard limits
- Copy during refinement: Should work (copy current visible draft)
- Navigate away during copy: Should handle gracefully

**Accessibility Tests:**
- Screen reader announces "Copied to clipboard"
- Keyboard navigation works for all copy buttons
- Focus management after copy
- ARIA labels on all copy buttons

**Performance Tests:**
- Copy action completes within 500ms
- Success toast appears within 100ms
- Navigation to history is smooth (< 300ms)

### Component Implementation Details

**CopySuccessToast Component:**
```typescript
// src/components/features/feedback/CopySuccessToast.tsx
interface CopySuccessToastProps {
  message: string;
  duration?: number;
  onClose: () => void;
}

export function CopySuccessToast({
  message,
  duration = 3000,
  onClose
}: CopySuccessToastProps) {
  useEffect(() => {
    const timer = setTimeout(onClose, duration);
    return () => clearTimeout(timer);
  }, [duration, onClose]);

  // Trigger confetti on mount
  useEffect(() => {
    triggerConfetti();
  }, []);

  return (
    <div className="fixed bottom-4 left-1/2 -translate-x-1/2 ...">
      <CheckIcon className="text-green-500" />
      <span>{message}</span>
    </div>
  );
}
```

**CopyButton Component:**
```typescript
// src/components/features/draft/CopyButton.tsx
interface CopyButtonProps {
  draftId: string;
  onCopy?: () => void;
  variant?: 'standalone' | 'toolbar';
}

export function CopyButton({
  draftId,
  onCopy,
  variant = 'standalone'
}: CopyButtonProps) {
  const [copied, setCopied] = useState(false);
  const copyDraftToClipboard = useChatStore(s => s.copyDraftToClipboard);

  const handleCopy = async () => {
    await copyDraftToClipboard(draftId);
    setCopied(true);
    onCopy?.();
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <button
      onClick={handleCopy}
      aria-label={copied ? 'Copied!' : 'Copy to clipboard'}
      className="..."
    >
      {copied ? <CheckIcon /> : <CopyIcon />}
    </button>
  );
}
```

**ChatService Extensions:**
```typescript
// src/services/chat-service.ts
export class ChatService {
  async completeDraft(draftId: string): Promise<void> {
    // Copy to clipboard
    const draft = await DraftService.getDraftById(draftId);
    await ClipboardUtil.copyMarkdown(draft.content);

    // Mark as completed in database
    await DraftService.markAsCompleted(draftId);

    // Update store (clears currentDraft, closes sheet)
    ChatStore.getState().completeDraft(draftId);

    // Navigate to history
    router.push('/history');
  }

  async copyDraftOnly(draftId: string): Promise<void> {
    const draft = await DraftService.getDraftById(draftId);
    await ClipboardUtil.copyMarkdown(draft.content);
    // Don't clear currentDraft - keep sheet open
  }

  async copyAndSaveDraft(draftId: string): Promise<void> {
    // Same as completeDraft but without navigation
    const draft = await DraftService.getDraftById(draftId);
    await ClipboardUtil.copyMarkdown(draft.content);
    await DraftService.markAsCompleted(draftId);
    ChatStore.getState().completeDraft(draftId);
  }
}
```

**DraftActions Integration:**
```typescript
// Update DraftActions component
const handleThumbsUp = async () => {
  // Full completion flow
  await ChatService.completeDraft(draftId);
  showSuccessToast('Draft saved to history!');
};

const handleCopyOnly = async () => {
  // Copy without closing
  await ChatService.copyDraftOnly(draftId);
  showSuccessToast('Copied to clipboard!');
};
```

### History Navigation Strategy

**After Completion:**
```typescript
// Navigate to history with highlight
router.push({
  pathname: '/history',
  query: { highlight: draftId }
});

// In history page, scroll to highlighted draft
useEffect(() => {
  if (router.query.highlight) {
    const element = document.getElementById(`draft-${router.query.highlight}`);
    element?.scrollIntoView({ behavior: 'smooth', block: 'center' });
    element?.classList.add('highlight-pulse');
  }
}, [router.query.highlight]);
```

**Highlight Animation:**
```css
/* In globals.css */
@keyframes highlight-pulse {
  0% { box-shadow: 0 0 0 0 rgba(100, 116, 139, 0.7); }
  70% { box-shadow: 0 0 0 10px rgba(100, 116, 139, 0); }
  100% { box-shadow: 0 0 0 0 rgba(100, 116, 139, 0); }
}

.highlight-pulse {
  animation: highlight-pulse 1s ease-out;
}
```

### Service Layer Extensions

**DraftService Completion:**
```typescript
// src/lib/db/draft-service.ts
export class DraftService {
  static async markAsCompleted(draftId: string): Promise<Draft> {
    const existing = await this.getDraftById(draftId);

    if (existing.status === 'completed') {
      // Already completed, just return
      return existing;
    }

    await db.drafts.update(draftId, {
      status: 'completed',
      completedAt: Date.now()
    });

    return this.getDraftById(draftId);
  }

  static async getCompletedDrafts(): Promise<Draft[]> {
    return await db.drafts
      .where('status')
      .equals('completed')
      .reverse()
      .sortBy('completedAt');
  }
}
```

**ChatStore Actions:**
```typescript
// src/lib/store/chat-store.ts
interface ChatStore {
  // Existing
  currentDraft: Draft | null;

  // New actions
  completeDraft: (draftId: string) => Promise<void>;
  copyDraftToClipboard: (draftId: string) => Promise<void>;
}

export const useChatStore = create<ChatStore>((set, get) => ({
  // Existing state...

  completeDraft: async (draftId: string) => {
    // Mark as completed
    await DraftService.markAsCompleted(draftId);
    // Clear from store (closes DraftViewSheet)
    set({ currentDraft: null });
  },

  copyDraftToClipboard: async (draftId: string) => {
    const draft = await DraftService.getDraftById(draftId);
    await ClipboardUtil.copyMarkdown(draft.content);
    // Don't clear currentDraft - keep sheet open
  },
}));
```

### Project Structure Notes

**Following Feature-First Lite Pattern:**
- New components in `src/components/features/feedback/` (toast)
- New components in `src/components/features/draft/` (copy button)
- Service extensions in existing files
- Store updates in `src/lib/store/chat-store.ts`

**Alignment with Unified Project Structure:**
- All feature code under `src/components/features/`
- Services orchestrate logic, don't touch DB directly from UI
- State managed centrally in Zustand stores
- Utility functions in `src/lib/utils/`

**No Conflicts Detected:**
- Completion is new status value, no conflicts
- Clipboard utility is new, no conflicts
- Navigation to history prepares for Epic 3

### Performance Requirements

**NFR-01 Compliance (Response Latency):**
- Copy action should complete within 500ms
- Success toast should appear within 100ms
- Navigation to history should be smooth (< 300ms)

**State Updates:**
- currentDraft should clear immediately on completion
- DraftViewSheet should close smoothly
- History page should render quickly

### Accessibility Requirements

**WCAG AA Compliance:**
- Copy buttons must have `aria-label`
- Success state must be announced to screen readers
- Focus management: Return focus after copy
- Keyboard shortcuts supported

**Visual Accessibility:**
- Success toast must be high contrast
- Avoid color-only indicators (use icons + text)
- Highlight animation must respect `prefers-reduced-motion`

### Security & Privacy Requirements

**NFR-03 & NFR-04 Compliance:**
- Clipboard operations are client-side only
- No draft content sent to server
- Completed drafts stay in IndexedDB
- No external API calls for copy/save

### References

**Epic Reference:**
- [Epic 2: "The Magic Mirror" - Ghostwriter & Draft Refinement](file:///home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/epics.md#epic-2-the-magic-mirror---ghostwriter--draft-refinement)
- [Story 2.4: Export & Copy Actions](file:///home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/epics.md#story-24-export--copy-actions)
- FR-07: "Users can 'One-Click Copy' the formatted text to clipboard"
- FR-09: "Users can edit the generated draft manually before exporting" (future enhancement)

**Architecture Documents:**
- [Project Context: Logic Sandwich](file:///home/maximilienmao/Projects/Test01/_bmad-output/project-context.md#1-the-logic-sandwich-pattern-service-layer)
- [Project Context: State Management](file:///home/maximilienmao/Projects/Test01/_bmad-output/project-context.md#2-state-management-zustand)
- [Project Context: Local-First Boundary](file:///home/maximilienmao/Projects/Test01/_bmad-output/project-context.md#3-local-first-data-boundary)

**UX Design Specifications:**
- [UX: Completion Reward Pattern](file:///home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/ux-design-specification.md#24-novel-ux-patterns)
- [UX: Success State](file:///home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/ux-design-specification.md#5-completion-if-liked)
- [UX: Micro-interactions](file:///home/maximilienmao/Projects/Test01/_bmad-output/planning-artifacts/ux-design-specification.md#micro-interactions)

**Previous Stories:**
- [Story 2.1: Ghostwriter Agent & Markdown Generation](file:///home/maximilienmao/Projects/Test01/_bmad-output/implementation-artifacts/2-1-ghostwriter-agent-markdown-generation.md) - Draft data structure
- [Story 2.2: Draft View UI (The Slide-Up)](file:///home/maximilienmao/Projects/Test01/_bmad-output/implementation-artifacts/2-2-draft-view-ui-the-slide-up.md) - DraftViewSheet and DraftActions
- [Story 2.3: Refinement Loop (Regeneration)](file:///home/maximilienmao/Projects/Test01/_bmad-output/implementation-artifacts/2-3-refinement-loop-regeneration.md) - Draft versioning pattern

## Dev Agent Record

### Agent Model Used

Claude Opus 4.5 (model ID: 'claude-opus-4-5-20251101')

### Debug Log References

Session file: `/tmp/claude/-home-maximilienmao-Projects/Test01/4ce6b396-ff74-42ee-be06-133000333628/scratchpad`

### Completion Notes List

**Story Analysis Completed:**
- Extracted story requirements from Epic 2, Story 2.4
- Analyzed previous Stories 2.1, 2.2, and 2.3 for established patterns
- Reviewed architecture for compliance requirements (Logic Sandwich, State Management, Local-First)
- Reviewed UX specification for completion reward and success state patterns
- Identified all files to create and modify

**Implementation Context Summary:**

**Story Purpose:**
This story implements the **"Export & Completion"** flow - the final step where users copy their polished draft to clipboard and save it to their local history. This completes the core value loop: Vent -> Generate -> Refine -> Export -> Save.

**Key Technical Decisions:**
1. **Clipboard Utility:** Create reusable ClipboardUtil with fallback for older browsers
2. **Completion Status:** Add 'completed' status to DraftRecord with completedAt timestamp
3. **Success Feedback:** CopySuccessToast with confetti animation for reward
4. **Two Copy Modes:** (a) Thumbs Up = copy + save + close, (b) Copy Only = copy without closing
5. **Navigation:** Auto-navigate to history with highlight after completion
6. **Haptic Feedback:** Vibration on mobile for tactile confirmation

**Dependencies:**
- No new external dependencies required
- Uses browser Clipboard API with fallback
- Reuses existing Zustand, Dexie infrastructure
- May need confetti library (canvas-confetti) for celebration effect

**Integration Points:**
- Thumbs Up in DraftActions (Story 2.2) triggers ChatService.completeDraft()
- Completion updates DraftRecord status in IndexedDB
- Clearing currentDraft closes DraftViewSheet (auto-close pattern from Story 2.2)
- Navigation to history prepares for Epic 3 implementation

**Files to Create:**
- `src/lib/utils/clipboard.ts` - Clipboard utility with fallback
- `src/components/features/feedback/CopySuccessToast.tsx` - Success feedback component
- `src/components/features/draft/CopyButton.tsx` - Standalone copy button

**Files to Modify:**
- `src/lib/store/chat-store.ts` - Add completion actions (completeDraft, copyDraftToClipboard)
- `src/lib/db/draft-service.ts` - Add markAsCompleted() method
- `src/services/chat-service.ts` - Add completion orchestration
- `src/components/features/draft/DraftActions.tsx` - Wire Thumbs Up to completion flow

**Testing Strategy:**
- Unit tests for clipboard utility (including fallback)
- Integration tests for full completion flow
- Edge case tests (clipboard denied, already completed, very long content)
- Accessibility tests (screen reader announcements, keyboard navigation)

**Draft Completion Pattern:**
- Thumbs Up triggers: Copy -> Toast -> Mark Completed -> Clear State -> Navigate
- Copy Only triggers: Copy -> Toast (no state change)
- Completed draft gets status='completed' and completedAt timestamp
- History view (Epic 3) will query by completedAt for reverse chronological order

**User Experience Flow:**
```
DraftViewSheet (Story 2.2)
    ↓
User taps Thumbs Up
    ↓
Clipboard.copy() - Copy Markdown to clipboard
    ↓
CopySuccessToast - "Copied to clipboard!" + confetti
    ↓
DraftService.markAsCompleted() - Update IndexedDB
    ↓
ChatStore.completeDraft() - Clear currentDraft (closes sheet)
    ↓
Navigate to /history with ?highlight=draftId
    ↓
History scrolls to and highlights the new entry
```

### File List

**New Files to Create:**
- `src/lib/utils/clipboard.ts` - Clipboard utility with fallback support
- `src/components/features/feedback/CopySuccessToast.tsx` - Success toast with confetti
- `src/components/features/draft/CopyButton.tsx` - Standalone copy button
- `src/lib/utils/clipboard.test.ts` - Clipboard utility tests
- `src/integration/export-copy-actions.test.ts` - End-to-end completion flow tests

**Files to Modify:**
- `src/lib/store/chat-store.ts` - Add completeDraft, copyDraftToClipboard actions
- `src/lib/db/draft-service.ts` - Add markAsCompleted() method and getCompletedDrafts()
- `src/lib/db/draft-service.test.ts` - Add completion method tests
- `src/services/chat-service.ts` - Add completion orchestration (completeDraft, copyDraftOnly)
- `src/components/features/draft/DraftActions.tsx` - Wire Thumbs Up and Copy button to completion
