diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3b96d6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,19 @@
+# .NET
+bin/
+obj/
+publish/
+*.user
+*.suo
+
+# SQLite
+*.db
+*.db-shm
+*.db-wal
+
+# IDE
+.vs/
+.vscode/
+*.swp
+
+# OS
+.DS_Store
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..64582df
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,169 @@
+# CLAUDE.md — Contexte projet MaBibli
+
+Ce fichier donne le contexte complet du projet à Claude Code. Lis-le en entier avant de commencer à coder.
+
+## Objectif du projet
+
+Application self-hosted de gestion de bibliothèque personnelle, à héberger sur YunoHost, accessible depuis smartphone et PC.
+
+## Fonctionnalités attendues (v1)
+
+1. **Catalogue de livres physiques** — liste, ajout, édition, suppression
+2. **Catalogue de livres numériques (ebooks)** — même chose, avec un champ format distinct du physique
+3. **Gestion de prêts**
+ - Prêter un livre à une personne (nom, date de prêt)
+ - Marquer comme récupéré (date de retour)
+ - Historique des prêts passés par livre (pas juste l'état courant)
+4. **Récupération automatique des infos via ISBN**
+ - Scan caméra du code-barres (EAN-13 / ISBN)
+ - Saisie manuelle de l'ISBN
+ - Dans les deux cas : appel à une ou plusieurs API pour pré-remplir titre, auteur, éditeur, couverture
+5. **Statuts de lecture** — à lire / en cours / lu (au minimum), assignable à chaque livre
+
+## Décisions techniques actées
+
+| Sujet | Décision | Pourquoi |
+|---|---|---|
+| Langage backend | C# / ASP.NET Core | Choix de l'utilisateur, typage fort |
+| Frontend | Blazor WebAssembly | Support PWA quasi natif (`dotnet new blazorwasm --pwa`), tout en C#, offline partiel |
+| Base de données | SQLite + Entity Framework Core | Fichier unique, pas de serveur DB séparé, adapté à un usage perso/familial |
+| Auth / multi-utilisateur | Déléguée au SSO de YunoHost | Pas de système de login custom à maintenir |
+| Hébergement | YunoHost, installation **native** (pas Docker) | YunoHost déconseille Docker pour ses apps (moins fiable, plus lourd) ; installation native = meilleures perfs sur petit matériel |
+| Packaging YunoHost | S'inspirer de [`radarr_ynh`](https://github.com/YunoHost-Apps/radarr_ynh) | Radarr est aussi en .NET, packagé sans Docker sur YunoHost. Leur `manifest.toml` montre un déploiement **self-contained** (`dotnet publish -r linux-x64 --self-contained`), donc pas besoin d'installer `dotnet-runtime` via apt côté serveur — le binaire embarque son propre runtime |
+| Scan ISBN | **ZXing.Net** (C#, Apache 2.0) exécuté dans le WASM ; le JS ne fournit que les pixels caméra | Décodage en C#, réutilisable hors navigateur si le projet évolue en scanner de bibliothèque. Voir la section dédiée ci-dessous |
+| Consultation hors-ligne | Cache local des données côté client (mécanisme à trancher) | Le besoin est de **consulter la bibliothèque existante** sans réseau, pas d'enrichir de nouveaux livres. Voir « Stratégie hors-ligne » |
+
+## Scan du code-barres — ZXing.Net (décision actée)
+
+Le décodage EAN-13 se fait en **C# avec [ZXing.Net](https://www.nuget.org/packages/ZXing.Net)** (`micjahn`, Apache 2.0), et non avec une bibliothèque JS type `html5-qrcode`.
+
+### Pourquoi
+
+- **Réutilisable hors navigateur.** Si le projet évolue vers un scanner de bibliothèque (app native, scan en masse, décodage d'une photo côté serveur), le code de décodage se transpose tel quel. Une bibliothèque JS serait à réécrire intégralement.
+- **Un seul langage**, cohérent avec le reste de la stack.
+- L'argument « offline » n'entre **pas** en compte ici : `html5-qrcode` fonctionne aussi hors-ligne (fichier JS servi par la PWA, aucun appel réseau). Ce n'est pas un critère de départage.
+
+### Mesures réelles (validées sur .NET 10, publish Blazor WASM OK)
+
+| Mesure | Résultat |
+|---|---|
+| Décodage EAN-13 propre (380×160) | 0,04 ms/frame |
+| **Pire cas** : frame 640×480 bruitée sans code-barres (échec) | 0,53 ms/frame |
+| Surcoût du payload PWA | +192 Ko (brotli) |
+
+Le pire cas est le chiffre qui gouverne le framerate : la majorité des frames caméra ne contiennent pas de code-barres lisible, et c'est l'échec de décodage qui coûte le plus cher.
+
+⚠️ Ces chiffres sont mesurés en **JIT x64 natif**. En Blazor WASM le code est *interprété* par défaut : compter un facteur ~10-20×, soit ~5-10 ms/frame — largement suffisant pour scanner à 10-15 fps. Activer `true` ramène ça à 1-2 ms, au prix d'un build nettement plus lent.
+
+### Pièges à connaître
+
+- **Le JS interop ne disparaît pas.** `getUserMedia` et `