## ADDED Requirements ### Requirement: Line numbers `CodeBlock` SHALL render line numbers in a left gutter for blocks with >1 line. Line numbers SHALL be 1-indexed, right-aligned, and muted in color (`text-muted-foreground`). Long files (≥1000 lines) SHALL not show line numbers by default (toggle override). #### Scenario: Multi-line block shows line numbers - **WHEN** a code block with 5 lines renders - **THEN** a left gutter shows numbers 1 through 5 - **AND** each number is right-aligned and muted ### Requirement: Diff gutter markers When the language prefix starts with `diff-` (e.g. `diff-typescript`), `CodeBlock` SHALL parse leading `+` / `-` / (space) characters on each line. Lines starting with `+` SHALL get a green left border and background tint. Lines starting with `-` SHALL get a red left border and background tint. Common lines SHALL render normally. The `+`/`-` prefix characters SHALL be stripped from the rendered text. #### Scenario: Diff block renders with gutter markers - **WHEN** a code block with language `diff-typescript` contains lines `+ const x = 1` and `- const y = 2` - **THEN** the first line has a green gutter marker and shows `const x = 1` - **AND** the second line has a red gutter marker and shows `const y = 2` ### Requirement: Multi-theme toggle `CodeBlock` SHALL display a theme toggle button that switches between `github-dark` and `github-light`. The initial theme SHALL match the app's current color scheme. The user's choice SHALL persist for the session (no localStorage). #### Scenario: User toggles theme - **WHEN** the user clicks the theme toggle button - **THEN** the code block re-renders with the alternate Shiki theme - **AND** the button icon reflects the current theme ### Requirement: Word-wrap toggle `CodeBlock` SHALL provide a word-wrap toggle button. When active, long lines wrap; when inactive, they overflow with horizontal scrolling. The default state SHALL be no-wrap (scroll). The toggle SHALL persist per-code-block for the session. #### Scenario: User toggles word wrap - **WHEN** the user clicks the word-wrap toggle - **THEN** long lines wrap to the container width - **AND** clicking again restores horizontal scroll ### Requirement: Collapsible long blocks `CodeBlock` SHALL auto-collapse blocks with ≥30 lines, showing the first 15 lines and a "Show {N} more lines" button. Clicking expands the full block. The collapsed state SHALL be indicated by a gradient fade at the cutoff. #### Scenario: Long block collapses - **WHEN** a code block has 50 lines - **THEN** the first 15 lines render with a fade gradient at the bottom - **AND** a "Show 35 more lines" button appears below - **AND** clicking the button expands all 50 lines ### Requirement: Inline copy with progress The copy button SHALL show an animated check icon on success and a brief "Copied" label that resolves after 1200ms. On copy failure, the button SHALL briefly show a red X before reverting. #### Scenario: Copy succeeds - **WHEN** the user clicks Copy and the clipboard write succeeds - **THEN** the button shows a check icon and "Copied" label for 1200ms #### Scenario: Copy fails - **WHEN** the user clicks Copy and the clipboard write fails - **THEN** the button shows a red X for 1200ms before reverting