diff --git a/MaBibli.Client/Composants/Patience.razor b/MaBibli.Client/Composants/Patience.razor
new file mode 100644
index 0000000..e66198d
--- /dev/null
+++ b/MaBibli.Client/Composants/Patience.razor
@@ -0,0 +1,25 @@
+@*
+ Indicateur d'attente pour les appels lents (lot L1).
+
+ ⚠️ Le besoin n'est pas décoratif. Une recherche BnF coûte environ une seconde par page, et
+ jusqu'à dix pages pour les nouveautés : sans rien à l'écran, l'application se lit comme
+ plantée, et l'utilisateur reclique — donc relance l'appel. C'est exactement ce que le lot H
+ avait constaté sur la bibliographie.
+
+ ⚠️ Un indicateur NE REMPLACE PAS un message d'échec. Une source muette garde ses états
+ EtatSourceBibliographie et son motif : ici on dit « ça travaille », jamais « ça a marché ».
+
+ role="status" et non role="alert" : l'attente s'annonce sans interrompre le lecteur d'écran.
+ L'animation est neutralisée sous prefers-reduced-motion (voir app.css).
+*@
+
+
+ @Message
+
+
+@code {
+ /// Ce qu'on attend, dit à l'utilisateur. Jamais un libellé générique si l'on sait mieux.
+ [Parameter, EditorRequired] public string Message { get; set; } = default!;
+
+ [Parameter] public string? Classe { get; set; }
+}
diff --git a/MaBibli.Client/Pages/AjoutIsbn.razor b/MaBibli.Client/Pages/AjoutIsbn.razor
index 9fab010..b48854e 100644
--- a/MaBibli.Client/Pages/AjoutIsbn.razor
+++ b/MaBibli.Client/Pages/AjoutIsbn.razor
@@ -82,9 +82,10 @@
*@
@if (_etape == Etape.Recherche)
{
-
- Recherche de @FormatageIsbn.Afficher(_isbn) à la BnF, puis chez OpenLibrary…
-
+ @* L1 : l'étape existait déjà pour que l'enchaînement du scan SE VOIE ; la rondelle dit en
+ plus que ça travaille encore, ce qu'un texte figé ne distingue pas d'un écran bloqué. *@
+
}
@if (_etape == Etape.Scan)
diff --git a/MaBibli.Client/Pages/Series.razor b/MaBibli.Client/Pages/Series.razor
index d3391a4..2634d1a 100644
--- a/MaBibli.Client/Pages/Series.razor
+++ b/MaBibli.Client/Pages/Series.razor
@@ -19,18 +19,18 @@
@* Créer une série depuis la liste : c'est le seul endroit d'où l'on part, et un écran de plus
pour un unique champ ne se justifierait pas. *@
-
+@* M1 : le champ et son bouton sur UNE ligne. Le champ prend la place restante, le bouton
+ garde la sienne et son libellé ne se tronque pas — vérifié jusqu'à 320 px. *@
+
-
-
diff --git a/MaBibli.Client/wwwroot/css/app.css b/MaBibli.Client/wwwroot/css/app.css
index 70dc28e..57bdcf1 100644
--- a/MaBibli.Client/wwwroot/css/app.css
+++ b/MaBibli.Client/wwwroot/css/app.css
@@ -1383,3 +1383,66 @@ body {
border-bottom-color: #f5d76e;
}
}
+
+/* --- Attente (lot L1) -------------------------------------------------
+ Un appel lent doit se voir : une recherche BnF coûte ~1 s par page, et
+ jusqu'à dix pages pour les nouveautés. Sans indicateur, l'écran se lit
+ comme planté et l'on reclique, ce qui relance l'appel.
+ ------------------------------------------------------------------- */
+
+.attente {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ color: var(--mb-texte-doux);
+ font-size: 0.9rem;
+ margin: 0.75rem 0;
+}
+
+.attente-rondelle {
+ flex: 0 0 auto;
+ width: 1rem;
+ height: 1rem;
+ border: 2px solid var(--mb-bord);
+ border-top-color: var(--mb-accent);
+ border-radius: 50%;
+ animation: attente-tourne 0.8s linear infinite;
+}
+
+@keyframes attente-tourne {
+ to { transform: rotate(360deg); }
+}
+
+/* Une animation perpétuelle est précisément ce que ce réglage demande d'éviter.
+ L'indicateur reste visible — c'est lui qui porte l'information, pas sa rotation. */
+@media (prefers-reduced-motion: reduce) {
+ .attente-rondelle {
+ animation: none;
+ border-top-color: var(--mb-accent);
+ border-right-color: var(--mb-accent);
+ }
+}
+
+/* --- Créer depuis une liste : champ + bouton sur une ligne (lot M1) ----
+ ⚠️ min-width: 0 sur le champ est ce qui fait tenir la ligne à 320 px : sans
+ lui, un élément de formulaire refuse de rétrécir sous sa largeur intrinsèque
+ et pousse le bouton hors de l'écran. Le bouton, lui, ne rétrécit pas et son
+ libellé ne se coupe pas — un bouton tronqué ne se lit plus.
+ ------------------------------------------------------------------- */
+
+.ligne-creation {
+ display: flex;
+ gap: 0.5rem;
+ align-items: stretch;
+ margin-bottom: 0.75rem;
+}
+
+.ligne-creation .champ-saisie {
+ flex: 1 1 auto;
+ min-width: 0;
+}
+
+.ligne-creation .bouton {
+ flex: 0 0 auto;
+ white-space: nowrap;
+}