diff --git a/CLAUDE.md b/CLAUDE.md
index 52ba41b..670242d 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -1766,6 +1766,26 @@ affichée, convertir en WebP). IDEES.md posait la question à mesurer avant de s
règle que pour l'AOT WASM — non fait tant que la taille du cache image n'a pas montré de
problème réel en usage.
+## Lot B — consulter d'abord, modifier ensuite (2026-08-20)
+
+`CarteLivre.razor` est le composant partagé des cartes du catalogue. Il reçoit un `LivreDto`,
+porte la couverture, les auteurs et les étiquettes de format, type, statut, prêt et éditeur,
+et le catalogue l'utilise lui-même. Une œuvre bibliographique possédée réutilise cette carte
+quand son livre est disponible.
+
+Pour une série, `/series/{id}` est la consultation : parenté, tomes, carte du livre rattaché,
+réordonnancement, rattachement, ajout et retrait restent des gestes courants. Seuls le titre,
+la parenté dans un cycle et la suppression sont dans `/series/{id}/edition`. Comme pour la
+fiche livre, le composant s'abonne à `LocationChanged` car les routes partagent le même paramètre.
+
+Pour les envies, `/souhaits` consulte et conserve l'export et la suppression courante.
+`/souhaits/ordre` porte exclusivement le réordonnancement (flèches et glisser-déposer), afin
+que ces contrôles ne puissent pas être déclenchés en faisant défiler la liste.
+
+Une œuvre bibliographique non possédée n'a pas de fiche locale. Son titre est donc un bouton
+qui déplie inline son ISBN et son nombre d'éditions, tandis que les œuvres possédées ouvrent
+leur fiche via la carte partagée.
+
## Installation YunoHost — éprouvée en production le 2026-08-18
Le paquet vit dans le dépôt `mabibli_ynh` (voir « Deux dépôts distincts »). Installé,
diff --git a/IDEES.md b/IDEES.md
index 7de93fa..20d850d 100644
--- a/IDEES.md
+++ b/IDEES.md
@@ -130,7 +130,7 @@ mesure montre un gain réel. Pas encore mesuré à l'échelle d'un vrai fonds.
---
-## Lot B — Consulter d'abord, modifier ensuite
+## Lot B — Consulter d'abord, modifier ensuite — traité le 2026-08-20
Un seul motif, déjà acté et éprouvé pour la fiche livre (`/livres/{id}` consulte,
`/livres/{id}/edition` modifie, le mode est **dans l'URL**), à étendre aux écrans qui présentent
@@ -145,6 +145,8 @@ encore un formulaire vivant sous le pouce.
- **B3. Bibliographie d'un auteur** : même carte que le catalogue, et un **clic ouvre le détail**
de l'œuvre au lieu de s'arrêter à une ligne.
+✅ Traité : voir la décision et les limites retenues dans `CLAUDE.md`.
+
⚠️ Le point commun des trois n'est pas cosmétique : c'est **une seule carte de livre** réutilisée
partout. Si les trois écrans réimplémentent la carte chacun de leur côté, les pastilles
divergeront comme le filtre a divergé (voir A2).
diff --git a/MaBibli.Client/Composants/CarteLivre.razor b/MaBibli.Client/Composants/CarteLivre.razor
new file mode 100644
index 0000000..32c9b4b
--- /dev/null
+++ b/MaBibli.Client/Composants/CarteLivre.razor
@@ -0,0 +1,57 @@
+
+
+@code {
+ [Parameter, EditorRequired] public LivreDto Livre { get; set; } = default!;
+ [Parameter] public RenderFragment? Actions { get; set; }
+}
diff --git a/MaBibli.Client/Pages/Bibliographie.razor b/MaBibli.Client/Pages/Bibliographie.razor
index 6f82d41..0e641dd 100644
--- a/MaBibli.Client/Pages/Bibliographie.razor
+++ b/MaBibli.Client/Pages/Bibliographie.razor
@@ -140,15 +140,26 @@ else if (_bibliographie is { } biblio)
{
@* La classe « oeuvre-possedee » grise la ligne : le livre est déjà sur l'étagère. *@
- @foreach (var (auteur, index) in livre.Auteurs.Select((a, i) => (a, i)))
- {
- @(index > 0 ? ", " : "")
- @auteur.Nom@if (auteur.Role != RoleAuteur.NonPrecise)
- {
- @* Comme le format et le type : seul ce qui a été choisi s'affiche. *@
- (@Libelles.RoleAuteur(auteur.Role).ToLowerInvariant())
- }
- }
-
- }
-
- @* Une seule ligne d'étiquettes, en lecture seule (IDEES.md) : la liste se
- parcourt, elle ne se manipule pas. Tout se modifie depuis la fiche. *@
-
- @* Un livre est physique par défaut : ne l'afficher que pour les ebooks,
- sinon l'étiquette est sur toutes les lignes et n'apprend rien. *@
- @if (livre.Format == Format.Numerique)
- {
- @Libelles.Format(livre.Format)
- }
-
- @* Même règle que le format : on n'affiche que ce qui a été CHOISI.
- « Non précisé » n'apprendrait rien et serait sur presque chaque ligne. *@
- @if (livre.TypeDocument != TypeDocument.NonPrecise)
- {
-
- @Libelles.TypeDocument(livre.TypeDocument)
-
- }
-
- @* Personnel : ce que montre cette pastille est MA lecture, pas celle du foyer.
- Pas de pastille = non commencé, l'absence de ligne en base. *@
- @if (livre.Statut is { } statut)
- {
-
- @Libelles.Statut(statut)
-
- }
-
- @* Un livre dehors l'est pour tout le foyer, contrairement au statut. *@
- @if (livre.PreteA is { } emprunteur)
- {
- Prêté à @emprunteur
- }
-
- @if (!string.IsNullOrWhiteSpace(livre.Editeur))
- {
- @livre.Editeur
- }
-
@@ -47,7 +51,7 @@ else
}
@* Les sous-séries d'un cycle : on les liste, on ne les déplie pas — chacune a son écran. *@
- @if (_filles.Count > 0)
+ @if (!ModeEdition && _filles.Count > 0)
{