## MODIFIED Requirements

### Requirement: Страницы веб-UI

Веб-UI SHALL предоставлять страницы: список загрузок с единым окном
добавления, **серверными фильтром по группе состояний, поиском и постраничной
выдачей (пагинацией)** (`/`), экран ревью одной загрузки (`/review/{id}`)
и страницу просмотра одной загрузки (`/download/{id}`) с распознаванием,
файлами→раскладкой, историей, блоком информации о торренте и — для сидирующих
задач — секцией живой статистики раздачи. Карточки активных (downloading)
загрузок в списке SHALL содержать индикатор прогресса. Фильтр, поиск и номер
страницы SHALL передаваться GET-параметрами запроса (например `f`, `q`, `page`)
и SHALL работать без клиентского JavaScript. Состояние `deleted` SHALL быть
скрыто в списке по умолчанию (с переключателем «показать всё»). Механика живого
обновления прогресса и наполнение секции раздачи определяются capability
`live-status`.

#### Scenario: Просмотр одной загрузки

- **WHEN** клиент открывает `GET /download/{id}` существующей загрузки
- **THEN** отрисовывается страница с её распознаванием, файлами, раскладкой и
  историей

#### Scenario: Прогресс активной загрузки в списке

- **WHEN** в списке есть загрузка в состоянии `downloading`
- **THEN** её карточка содержит индикатор прогресса (прогресс-бар со скоростью
  и ETA)

#### Scenario: Удалённые скрыты по умолчанию

- **WHEN** в списке есть загрузки в состоянии `deleted` и фильтр «показать
  всё» не включён
- **THEN** они не отображаются, но доступны при включённом переключателе

#### Scenario: Пагинация списка

- **WHEN** загрузок под текущим фильтром больше, чем помещается на одну
  страницу, и клиент запрашивает `GET /?page=N`
- **THEN** возвращается N-я страница результатов и элементы навигации по
  страницам, сохраняющие текущие фильтр и поисковый запрос

#### Scenario: Серверный фильтр и поиск

- **WHEN** клиент запрашивает список с параметрами фильтра по состоянию и/или
  строкой поиска (`GET /?f=review&q=дюна`)
- **THEN** сервер возвращает только подходящие загрузки (по группе состояний и
  совпадению строки в названии, любом идентификаторе загрузки — `download.id`
  ИЛИ infohash — и контексте), отфильтрованные на стороне БД, а не на клиенте

### Requirement: Клиентские взаимодействия без сборки

Веб-UI SHALL реализовывать клиентскую логику без шага сборки и без реактивных
фреймворков: копирование идентификатора загрузки (vanilla JS) и раскрытие
контекста нативным `<details>`. Основной копируемый идентификатор в карточке
списка и в шапке страницы просмотра SHALL быть `download.id` (ULID) — тот же
ключ, что пишется в логи (`download_id`). Все действия над загрузкой SHALL
выполняться через формы/htmx (раундтрип на сервер), без клиентского пересчёта
доменного состояния.

#### Scenario: Копирование идентификатора загрузки

- **WHEN** пользователь нажимает кнопку копирования рядом с идентификатором
  загрузки (`download.id`) в карточке списка или шапке страницы просмотра
- **THEN** значение `download.id` копируется в буфер обмена без перезагрузки
  страницы
