# 014 — Library reading progress badges

**Status:** Implemented  
**Created:** 2026-06-04

## Objective

Show accurate reading state on library book cards using saved EPUB progress instead of always displaying "Want to Read" (`Quiero leer`).

## Data source

- `GET /api/books/ebooks/` returns `progress` (0–100) from `ReadingProgress.current_position` via `EBookListSerializer.get_progress`.
- Progress is updated by the web reader (`useEpubReader` → `PATCH .../progress/`).

## Display rules

| Progress | `opened` | Badge | Cover extra |
|----------|----------|-------|-------------|
| `null` or `0` | false | Want to Read | — |
| `0` | true | Opened | — |
| `1–98` | — | Reading · N% | Green progress bar on cover |
| `≥ 99` | — | Finished | — |

**Opened** is set when the reader first displays (CFI saved, 0% progress). Turning pages moves to **Reading**.

Threshold constant: `FINISHED_PROGRESS_THRESHOLD = 99` in `frontend/src/utils/libraryStatus.ts`.

## Frontend changes

| File | Change |
|------|--------|
| `utils/libraryStatus.ts` | `deriveReadingStatus`, `normalizeProgressPercent` |
| `pages/Library.tsx` | Map API progress → status; badge labels; client-side status filter |
| `locales/en-US.ts`, `es-ES.ts` | `library.readingStatus.readingWithProgress` |
| `pages/Library.module.css` | Cover progress bar styles |

## Status filter

The reading-status filter in the library panel now filters client-side by derived status (`want_to_read`, `reading`, `finished`).

## Verification

1. New upload → **Want to Read** / **Quiero leer**
2. Partial read → **Reading · N%** + progress bar
3. Near end (≥ 99%) → **Finished** / **Terminado**
4. Filters by Leyendo / Terminado work as expected
