## Why

Сейчас действия над загрузкой (откат, привязать заново, распознать заново,
уточнить, применить и т.д.) — это POST-формы с PRG-редиректом: после действия
браузер уходит на другую страницу и теряет контекст. Откат со страницы
загрузки `/download/{id}` и из карточки списка одинаково выкидывает на `/`, а
перераспознавание на `/review/{id}` перезагружает страницу с прыжком скролла
наверх. Пользователь хочет оставаться там, где действовал: действие со списка —
остаёшься в списке, со страницы загрузки/ревью — остаёшься на ней.

## What Changes

- Мутирующие UI-действия выполняются через **htmx-swap на месте** вместо
  server-side PRG-редиректа: сервер отвечает обновлённым HTML-фрагментом той
  области, которую затронуло действие, htmx подменяет её в DOM без навигации.
  Паттерн уже применяется в `reviewBlockAction` (выбор источника) — расширяем
  его на остальные действия.
- **Карточка в списке** (`/`): действия `undo`, `relink`, `retry`, `cancel`
  подменяют карточку (`<article class="card">`) на месте — обновлённое
  состояние, бейдж и набор кнопок. Фильтр/поиск/пагинация/прокрутка не
  сбрасываются.
- **Страница загрузки** (`/download/{id}`): те же действия обновляют содержимое
  страницы на месте (без перехода и без прыжка скролла), отражая новое
  состояние.
- **Страница ревью** (`/review/{id}`): **петлевые** действия распознавания —
  `rerecognize`, `refine` (и уже работающий выбор источника) — обновляют экран
  на месте (без перезагрузки и прыжка скролла). Так как они асинхронны (переводят
  загрузку в `recognizing`), своп отдаёт состояние `recognizing`, а экран сам
  **допалливает** готовый план htmx-фрагментом (`GET /fragments/downloads/{id}/review`,
  по образцу `progress`/`seeding`) и автоматически сменяется на план по
  завершении — без ручного обновления. **Выходы** из ревью (`apply` → done,
  `defer` → deferred, `cancel` → cancelled) уводят с экрана (загрузка покидает
  ревью), поэтому остаются навигацией/редиректом. Отдельная кнопка
  перераспознавания на `/download/{id}` НЕ добавляется — ревью считается частью
  «страницы загрузки», действие остаётся в ревью-потоке.
- **Деградация без JS сохраняется**: формы остаются обычными POST; при
  отсутствии htmx (нет заголовка `HX-Request`) сервер отвечает прежним
  PRG-редиректом, поведение не ломается.
- **Ошибки действий** показываются на месте (в подменённом фрагменте), а не
  только через `?err=` после редиректа.

Новых зависимостей нет: Alpine.js/SPA не вводятся, стек остаётся htmx-first
(см. решение `2026-06-30-web-ui-design-port`).

## Capabilities

### New Capabilities
<!-- Нет новых capability — меняется поведение существующих. -->

### Modified Capabilities
- `web-ui`: действия над карточкой/страницей загрузки выполняются htmx-swap'ом
  фрагмента на месте (без навигации и сброса контекста списка), с graceful
  degradation на PRG-редирект без htmx.
- `review`: петлевые действия ревью (`rerecognize`, `refine`) обновляют экран
  на месте htmx-свопом, не перезагружая страницу и не сбрасывая прокрутку;
  выходы из ревью (`apply`/`defer`/`cancel`) остаются навигацией.

## Impact

- **Код**: `internal/httpapi` — обработчики действий (`review.go`,
  `httpapi.go`): вместо `redirect*` отвечать фрагментом (HTTP 200) при
  `HX-Request`, сохранив редирект-ветку; извлечь `buildCardView`/
  `buildDownloadView`; новый fragment-эндпоинт `handleFragReview` для
  авто-поллинга recognizing (`live.go`).
- **Шаблоны** (`web/templates`): выделить переиспользуемые фрагменты —
  карточка списка (в партиал), «главная область» страницы загрузки, тело
  ревью; проставить `hx-post`/`hx-target`/`hx-swap` на формы действий, скрытое
  поле `surface`, поллер на блок `recognizing`.
- **Зависимости**: без изменений (htmx уже вендорится).
- **Тесты**: обработчики действий — проверка ветвления `HX-Request` →
  фрагмент vs редирект.
- **Вне scope**: живой поллинг телеметрии (`live-status`) не трогаем;
  клиентских фреймворков не добавляем.
