fix(mobile): barre de thèmes masquée, modale @ hors écran, pastille d'avatar
CI / build-and-test (push) Successful in 14m14s

Cinq correctifs signalés sur le mode mobile et le mode desktop.

1. La modale « @ » était confinée dans le header (desktop + mobile)
   <header> portait `backdrop-blur-sm`, et `backdrop-filter` fait de l'élément
   le containing block de ses descendants en position:fixed. Les overlays du
   provider-picker (et du menu Ctrl+K) se résolvaient donc contre le header :
   mesuré 1440x64 au lieu de 1440x900, dialogue réduit à 32px de haut pour 466px
   de contenu, haut de la fenêtre inatteignable.
   Le flou passe sur une couche enfant (`-z-10`) qui n'est pas un ancêtre des
   overlays : `fixed` redevient relatif au viewport.
   Desktop : dialogue 512x468 centré. Mobile : 358x686, entièrement visible.

2. La barre de thèmes disparaissait sous le header (desktop + mobile)
   `--header-offset` vaut 56/64px, mais le header mesure 57/65px (bordure) et
   118px quand la feuille de recherche mobile est ouverte. La barre était donc
   déjà glissée dessous, et totalement invisible dans ce dernier cas
   (hauteur visible mesurée : 0px).
   HeaderComponent publie maintenant sa hauteur réelle dans `--header-measured`
   via ResizeObserver ; `--header-offset` l'utilise quand elle existe et garde
   la valeur statique en repli. Barre visible dans tous les cas, y compris
   feuille de recherche ouverte.

3. Barre de thèmes : icônes seules sur mobile
   Les libellés sont masqués sous md (`aria-label` conservé pour
   l'accessibilité). 7 pastilles visibles au lieu de 3, sans scroll.

4. Avatar en pastille
   `.avatar-circle` est renforcé : `rounded-full` dans le markup plus
   `border-radius: 9999px !important`, `aspect-ratio: 1/1`, min-width/min-height
   et `line-height: 1`, pour qu'aucun style de thème ne puisse le dégrader en
   rectangle.

Vérifié : audit navigateur sur 17 routes x 320/390/768/1440 px — aucun
débordement horizontal, barre de thèmes visible partout ; tests du dépôt verts ;
build production OK.
This commit is contained in:
2026-09-28 16:25:55 -04:00
parent fa775497ee
commit 9fb0ce7549
4 changed files with 74 additions and 17 deletions
@@ -47,16 +47,18 @@
</button>
<!-- Replier la bande : action disponible uniquement dans le header.
On phones the rail is edge-to-edge with a swipe affordance instead of
the reserved arrow gutters. -->
On phones the rail is edge-to-edge and shows icons only — the labels do
not fit and force the strip to scroll for the first few themes. -->
<div class="scroll-rail no-scrollbar md:overflow-x-auto" #scroll (wheel)="onWheel($event)">
<ul role="tablist" aria-label="Themes" class="flex min-w-max items-center gap-2 px-3 py-2 md:px-12">
<ul role="tablist" aria-label="Themes" class="flex min-w-max items-center gap-1.5 px-3 py-2 sm:gap-2 md:px-12">
<li *ngFor="let t of displayedThemes(); let i = index" class="shrink-0">
<button
#pill
role="tab"
type="button"
class="chip px-3 py-1.5 rounded-full text-sm font-medium border transition-colors whitespace-nowrap focus:outline-none focus:ring-2 focus:ring-red-500"
[attr.aria-label]="themesSvc.i18nLabel(t)"
[attr.title]="themesSvc.i18nLabel(t)"
class="chip inline-flex items-center justify-center gap-1.5 rounded-full border px-3 py-1.5 text-sm font-medium transition-colors whitespace-nowrap focus:outline-none focus:ring-2 focus:ring-red-500 md:px-3.5"
[class.bg-slate-100/10]="activeSlug() === t.slug"
[class.text-white]="activeSlug() === t.slug"
[class.border-red-500]="activeSlug() === t.slug"
@@ -66,8 +68,8 @@
(click)="goToTheme(t.slug)"
(keydown)="onKeydown($event, i)"
>
<span class="mr-1 select-none">{{ t.emoji }}</span>
<span>{{ themesSvc.i18nLabel(t) }}</span>
<span class="select-none text-base leading-none md:text-base">{{ t.emoji }}</span>
<span class="hidden md:inline">{{ themesSvc.i18nLabel(t) }}</span>
</button>
</li>
</ul>