# 🎯 Prompt Windsurf — ObsiViewer Nimbus UI (Desktop + Mobile) ## ObsiViewer → UI/UX "Nimbus-like" (simple, dense, rapide) **Rôle & mode :** Agis comme **Staff Frontend Engineer Angular 20 + UX designer**. Raisonnement détaillé autorisé. Tu as les pleins pouvoirs de refactor UI, d'ajout de composants, et de migration CSS vers Tailwind. Conserve la compatibilité de toutes features existantes. **Contrainte majeure :** L'interface doit être **100% responsive** et compatible à 100% avec les modes Desktop et Mobile (téléphone et tablette). Un **bouton toggle** dans la navbar permet de basculer entre l'ancienne interface et la nouvelle sans perte d'état. Assure une expérience fluide sur tous les appareils, avec des adaptations spécifiques pour les écrans tactiles (touch targets ≥44x44px), gestures (swipe, pull-to-refresh), et breakpoints optimisés pour téléphones (xs/sm), tablettes (md), et desktops (lg/xl/2xl). --- ## Contexte rapide * Projet : **ObsiViewer** (Angular 20 + Tailwind, Node/Express backend). * Objectif : Refondre l'interface selon un design **Nimbus Notes / FuseBase Note**-like, en intégrant fidèlement la lecture anatomique et UX décrite ci-dessous. * Cœurs d'usage : navigation par **dossiers**, **tags**, **recherche**, **lecture markdown** plein écran, **ToC** à droite, **tri et filtres** rapides. * **Nouveauté** : Design adaptatif complet (Desktop/Mobile/Tablet) avec UI toggle persisté. ### Description détaillée de l'interface Nimbus (à reproduire fidèlement) Voici une **lecture “anatomique” et UX** de l’interface Web de *Nimbus Notes / FuseBase Note*, rédigée comme le ferait un lead designer qui doit la reproduire fidèlement. Cette description guide toute la refonte et doit être intégrée à 100% dans l'implémentation, en veillant à la compatibilité Desktop/Mobile/Tablet (par exemple, colonnes empilées ou onglets sur mobile, drawers tactiles sur tablette). --- # 1) Philosophie produit (ce qui guide toute l’UI) * **Workspace-first** : tout vit dans un *espace de travail* isolé (pages, dossiers, tags, membres). On change d’espace, on change d’univers de contenu – ce n’est pas un simple filtre global. ([FuseBase][1]) * **Organisation bi-axiale** : **dossiers (hiérarchie)** + **tags (multi-catégories)**. Les dossiers structurent, les tags donnent le contexte transversal et la recherche rapide. ([FuseBase][2]) * **Recherche d’abord, navigation ensuite** : la *top bar* met la recherche au centre, avec des *chips* de filtres persistants (“All folders / All tags / All pages”) qui rendent l’état des filtres **visible, éditable et réinitialisable** sans quitter le flux. * **Progressive disclosure** : menus condensés, panneaux contextuels (picker dossiers/tags, panneau d’outline à droite) qui n’apparaissent que “on demand” pour ne jamais surcharger l’écran. * **Un contenu, plusieurs façades** : la page est éditée dans l’app interne, mais peut être **partagée** ou **publiée** dans un **Portal** externe *brandé*. Les commandes “Add to portal / Share” sont toujours visibles dans l’éditeur. ([FuseBase][3]) --- # 2) Layout global (3 panneaux + overlays) ## A. Barre supérieure (globale) * **Champ de recherche** large, centré, avec **icône filtre** (entonnoir) qui ouvre les options avancées. * Bouton **“+ Page”** (CTA positif turquoise) : création immédiate dans le contexte courant (workspace + dossier sélectionné). * À droite, dans la *content toolbar* du document : **Ask AI**, **Add to portal**, **Share**, loupe locale, pièces jointes/annotations, **toggle plein écran**, menu kebab. (Les intitulés et la présence “Ask AI / Portals” sont aussi documentés côté guides.) ([FuseBase][4]) ## B. Colonne de gauche (navigation primaire) * **Quick Links** puis **Folders / Tags / Trash** — arborescence compacte avec triangles de disclosure. * **Création de sous-dossier au survol** via un **+** qui apparaît à droite du dossier (pattern hover-reveal). ([FuseBase][2]) * **Sélecteur d’organisation/workspace** et **switch de thème** dans le footer du rail (menu avatar : “Light theme”, Settings, etc.). Le changement d’espace est aussi accessible depuis la colonne et le menu avatar. ([FuseBase][5]) * **État** : le dossier actif est surligné, le compteur de pages peut apparaître à côté des libellés (donnant un feedback rapide sur la densité). **Traits de design** * Icônes de dossiers colorées + emojis autorisés dans les noms (lisibilité + repères mnémotechniques). * Densité **compacte** mais respirante (gouttière + padding régulier), contrastes élevés en dark mode. ## C. Colonne centrale (index / résultats) * En-tête d’index : *chips* **All folders ▾**, **All tags ▾**, **All pages ▾**. Chacune ouvre un **picker flottant** (overlay) : * **Picker dossiers** : recherche interne, sélection multi, sous-dossiers avec *chevron/›*, actions **Clear / Done**, badges *+1*, *+15* reflétant le nombre de sélections. * **Picker tags** : liste alphabétique, **checkmarks** pour les tags actifs, **Clear / Done** en bas. * En dessous, **liste des pages** : tuiles en une ligne avec **titre**, **date**, **snippet** (extrait), **petites icônes** (ex. carte *bookmark* pour les liens sauvegardés). Le *hover* change légèrement le fond ; l’élément sélectionné est **surligné** (bleu). * **Message “Found pages: N”** + lien **Clear** lorsque des filtres sont actifs (feed-back lisible de l’état de recherche). **Subtilités d’usage** * Les *chips* de filtre restent visibles pendant la navigation (ancrage cognitif). * Chaque picker possède sa **barre de recherche locale**, ce qui réduit la charge mentale sur de gros jeux de tags/dossiers. * Les *chips* affichent des **badges de comptage** (+1, +2) et un **caret** pour signifier qu’il s’agit d’un *menu stateful*, pas d’un simple label. ## D. Panneau de droite (lecteur/éditeur) * **Titre de page** très lisible, méta-ligne en dessous (ex. *Add tags*), mini-icônes de statut. * **Contenu riche** : titres, listes, *inline code*, *code fences*, callouts, objets embarqués, cartes “**Bookmark**” (prévisualisation d’URL avec titre/description/vignette). ([FuseBase][6]) * **Toolbar du document** (droite) : * **Ask AI** (génération, résumé, etc.) ; **Add to portal** (publier la page dans une arborescence publique/privée) ; **Share** (lien partagé, droits). ([FuseBase][3]) * Loupe/“find in page”, attachements, rappel/notification si activés, **plein écran** avec raccourci (tooltip). * **Panneau latéral contextuel (outline)** : petit bouton *hamburger* rond “dans la page” (à mi-hauteur, côté droit) qui **déplie un rail d’outline** listant les headings H1–H6 ; clic = **scroll-to**. (Très utile sur documents longs, *progressive disclosure*). **Édition & Portals (workflow)** * L’édition se fait **directement** côté web, et l’on peut **pousser** vers un *Portal* sans passer par un autre back-office : “Add to portal” + *drag & drop* vers la structure du Portal (depuis le rail). ([FuseBase][3]) ## E. Overlays & états transitoires * **Pickers** (Folders/Tags) : overlays centrés au-dessus de la colonne des résultats, avec **Clear/Done** persistants en pied. * **Dark / Light** : toggles dans le menu avatar ; la **typographie/balances de gris** sont recalibrées (mode light très clair, mode dark très contrasté) pour garder le même *information scent*. * **Notifications/Tooltips** : discrets, ancrés aux contrôles (ex. plein écran). --- # 3) Micro-interactions & patterns récurrents * **Hover-reveal** : le “+” pour créer un sous-dossier n’apparaît qu’au survol → garde l’arborescence propre. ([FuseBase][2]) * **Pills / Chips** avec **caret** + **badge** = *stateful filter* (on comprend d’un coup d’œil ce qui est filtré). * **Sélection persistante** dans la liste : l’élément actif garde un **fond** et une **bordure** turquoise ; on ne “perd” pas la page lue. * **Clear partout** : dans les pickers et au niveau global – la stratégie de *reset rapide* est omniprésente (réduction du coût d’exploration). * **Hiérarchie visuelle stricte** : H1–H3 très différenciés, marges généreuses, *line-height* confortable (lecture longue). --- # 4) Contenus & types spéciaux * **Bookmarks** : carte enrichie (titre + description + vignette) → meilleure *scanability* des liens sauvegardés que du simple texte. ([FuseBase][6]) * **Tables/Databases** : vues avec tri, filtres, commentaires cellule, panneau de calcul (présents dans l’écosystème guides). ([FuseBase][4]) * **Web Clipper** : amène des pages propres (sans pubs), cohérent avec la carte Bookmark ; logique de capture → enrichissement → partage. ([FuseBase][7]) --- # 5) Accessibilité & lisibilité * **Contrastes sûrs** (notamment en dark), tailles de cible suffisantes sur la top bar et les chips. * **Iconographie descriptive** (dossier, tag, favoris, web card…) + emojis pour ancrage visuel rapide. * **Réduction du *cognitive load*** : les options rarement utilisées sont “cachées” (kebab, hover-reveal), les actions courantes sont **toujours** visibles (Search, +Page, filtres). --- # 6) Ce que l’UX “raconte” (le mode d’emploi implicite) 1. **Trouver** : commencez par *Search* et affinez avec *All folders / All tags*. 2. **Parcourir** : si vous êtes “dans” un dossier, l’index au centre sert de *tableau de bord* (dates + snippets). 3. **Éditer / Enrichir** : dans le panneau de droite, vous rédigez, taggez, joignez, bookmarquez. 4. **Diffuser** : *Share* pour du partage direct, **Add to portal** pour publier dans un espace externe gouverné (droits, branding). ([FuseBase][8]) --- # 7) Détails visibles dans vos captures (à reproduire à l’identique) * **Top bar** : champ de recherche + icône filtre + **+ Page** (CTA turquoise). * **Trio de chips** : “All folders ▾” (multi-sélection hiérarchique), “All tags ▾” (liste à coches), “All pages ▾”. * **Liste** : ligne compacte, *hover*, *selected state* bleu, **date** en gris, **snippet** tronqué, petite icône (ex. “shopping cart” pour bookmark e-commerce). * **Panneau d’outline** (badge hamburger circulaire flottant à droite du contenu) → rail d’outline repliable. * **Menu avatar (footer gauche)** : **Light theme**, Settings, Upgrade, logout, etc. * **Dark/Light** : la *skin* claire conserve l’architecture et les espacements, en ne changeant que la palette et les ombres. --- ## TL;DR — Nimbus en 8 principes à retenir (pour inspirer un redesign) 1. **Trois panneaux** stables (nav / index / contenu) + **overlays** transitoires. 2. **Filtres persistants** sous forme de **chips** toujours visibles. 3. **Pickers** riches (recherche locale, checkmarks, Clear/Done). 4. **Outline contextuel** à droite, déclenché **dans** la page. 5. **Action de création** unique, toujours au même endroit (**+ Page**). 6. **Workspaces** strictement séparés ; **Portals** pour l’externe. ([FuseBase][1]) 7. **Bi-axe dossiers/tags** (structure + sens transversal). ([FuseBase][2]) 8. **Share/Add to portal** omniprésents : écrire → publier est un **continuum**. ([FuseBase][8]) Si tu veux, je peux te livrer juste après un *spec UI* prêt à coder (grid, tailles, tokens couleur, comportements exacts des pickers) ou un **prompt Windsurf** pour cloner ces patterns dans ObsiViewer. [1]: https://thefusebase.com/guides/basics/workspaces/?utm_source=chatgpt.com "Workspaces" [2]: https://thefusebase.com/guides/basics/folders-and-tags/?utm_source=chatgpt.com "Folders and Tags" [3]: https://thefusebase.com/guides/client-portal/how-to-manage-your-portal-from-the-web-version/?utm_source=chatgpt.com "How To Manage Your Portal From The Web Version" [4]: https://thefusebase.com/guides/?utm_source=chatgpt.com "Guides Archive" [5]: https://nimbusweb.me/fr/guides/getting-started/how-to-navigate/?utm_source=chatgpt.com "How to navigate" [6]: https://nimbusweb.me/guides/basics/bookmarks/?utm_source=chatgpt.com "Bookmarks" [7]: https://thefusebase.com/guides/web-clipper/nimbus-clipper-for-google-chrome/?utm_source=chatgpt.com "Nimbus Clipper for Google Chrome" [8]: https://thefusebase.com/guides/embedding-sharing/shared-folders-and-pages/?utm_source=chatgpt.com "Shared folders and pages" --- ## 🎯 Objectif final (résumé) ### Desktop (≥1024px) Refondre l'interface ObsiViewer en **3 colonnes** respectant fidèlement la description Nimbus : 1. **Sidebar gauche** (Quick Links, Dossiers arborescents, Tags) — Redimensionnable. 2. **Colonne centrale** Liste des pages (recherche, filtres dossiers/tags, tris, résultats virtualisés). 3. **Vue de page** à droite (lecture markdown, barre d'actions, **panneau sommaire/ToC** docké à l'extrême droite). Le tout **compact, performant, thème clair/sombre**, navigation au clavier, états persistés localement. ### Mobile/Tablet (<1024px) Une navigation **par onglets/drawer** intelligente, adaptée à la philosophie Nimbus (progressive disclosure, chips persistants, overlays tactiles) : - **Tab 1 : Sidebar** (dossiers, tags, recherche) — Panneau full-width ou drawer collapsible. - **Tab 2 : Liste** (résultats de recherche) — Full-width scrollable. - **Tab 3 : Page** (markdown) — Full-width avec ToC inline collapsible ou drawer. **Gestures** : Swipe horizontal pour navigation onglets, pull-to-refresh, tap = open item. Assure que les chips de filtres et pickers sont optimisés pour touch (tailles augmentées, overlays pleine largeur sur mobile). --- ## 📋 Architecture Feature Flag & Toggle ### 1) Toggle UI dans la NavBar Ajouter un **bouton toggle** dans `src/app/layout/app-navbar/app-navbar.component.ts` : ```html
``` ### 2) Service de gestion du mode UI Créer `src/app/shared/services/ui-mode.service.ts` : ```typescript import { Injectable, signal } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class UiModeService { // Signal pour réactivité fine-grained isNimbusMode = signal(this.loadUIMode()); constructor() {} toggleUIMode() { const newMode = !this.isNimbusMode(); this.isNimbusMode.set(newMode); localStorage.setItem('obsiviewer-ui-mode', newMode ? 'nimbus' : 'legacy'); } private loadUIMode(): boolean { if (typeof localStorage === 'undefined') return false; const saved = localStorage.getItem('obsiviewer-ui-mode'); return saved ? saved === 'nimbus' : true; // Nimbus par défaut } } ``` ### 3) Layout wrapper avec feature flag Créer `src/app/layout/app-shell-adaptive/app-shell-adaptive.component.ts` : ```typescript import { Component, inject } from '@angular/core'; import { UiModeService } from '@app/shared/services/ui-mode.service'; import { AppShellNimbusLayoutComponent } from '../app-shell-nimbus/app-shell-nimbus.component'; import { AppShellLegacyLayoutComponent } from '../app-shell-legacy/app-shell-legacy.component'; @Component({ selector: 'app-shell-adaptive', template: ` @if (uiMode.isNimbusMode()) { } @else { } `, standalone: true, imports: [AppShellNimbusLayoutComponent, AppShellLegacyLayoutComponent], }) export class AppShellAdaptiveComponent { uiMode = inject(UiModeService); } ``` --- ## 🎨 Responsive Design Strategy ### Breakpoints Tailwind (standard) ```typescript // tailwind.config.js module.exports = { theme: { screens: { 'xs': '320px', // iPhone SE 'sm': '640px', // Petites tablettes 'md': '768px', // iPad, tablettes 'lg': '1024px', // Desktop compact 'xl': '1280px', // Desktop standard '2xl': '1536px', // Larges écrans }, }, }; ``` ### Mobile First Approach **Développer pour mobile d'abord, puis enrichir pour desktop.** Assure que tous les éléments Nimbus (chips, pickers, outline) sont tactiles et responsifs : par exemple, chips scrollables horizontalement sur mobile, pickers en modales pleine largeur sur téléphone/tablette. --- ## 📱 Layouts Responsifs ### Desktop Layout (≥1024px) ``` ┌─────────────────────────────────────────────────────────┐ │ NAVBAR (Dark, fixed, h-14) │ ├────────────────┬──────────────────┬──────────────────────┤ │ │ │ │ │ SIDEBAR │ RESULT LIST │ NOTE VIEW + TOC │ │ (240-440px) │ (virtualized) │ (Resizable) │ │ Resizable │ │ │ │ │ │ │ │ - Quick │ - Search bar │ - Markdown │ │ Links │ - Filters │ - ToC drawer │ │ - Folders │ - Items (80px) │ - Actions bar │ │ - Tags │ - Pagination │ │ │ │ │ │ └────────────────┴──────────────────┴──────────────────────┘ ``` ### Tablet Layout (768px ≤ width < 1024px) ``` ┌──────────────────────────────────────┐ │ NAVBAR + Toggle (fixed, h-14) │ ├──────────────────────────────────────┤ │ TAB NAVIGATION (fixed, bottom) │ │ [Sidebar] [List] [Page] [ToC] │ ├──────────────────────────────────────┤ │ │ │ ACTIVE TAB CONTENT (scrollable) │ │ - Drawer si besoin │ │ - Full-width panels │ │ │ └──────────────────────────────────────┘ ``` ### Mobile Layout (<768px) ``` ┌──────────────────────────────────┐ │ NAVBAR (compact, h-12) │ │ [Menu] [Search] [Toggle] │ ├──────────────────────────────────┤ │ │ │ TAB/DRAWER NAVIGATION │ │ [≡] [🔍] [📄] [📋] │ │ │ │ CONTENT AREA (Full-width) │ │ - Drawer sidebar (80vw left) │ │ - Swipeable list (list tab) │ │ - Markdown full-screen (page) │ │ - Inline ToC (toggle button) │ │ │ ├──────────────────────────────────┤ │ Bottom Navigation (sticky) │ │ Tab buttons (4 icônes) │ └──────────────────────────────────┘ ``` --- ## 🎬 Composants Nimbus Responsifs ### Desktop/Mobile Variants Chaque composant doit avoir des **variants responsifs** intégrant les patterns Nimbus (hover-reveal sur desktop, tap-reveal sur mobile ; chips avec badges tactiles) : ``` app-left-sidebar/ ├── app-left-sidebar.component.ts # Logique partagée ├── app-left-sidebar.desktop.component.ts # ≥1024px (fixed, resizable) └── app-left-sidebar.mobile.component.ts # <1024px (drawer) app-center-list/ ├── app-center-list.component.ts ├── app-center-list.desktop.component.ts # ≥1024px (2 colonnes) └── app-center-list.mobile.component.ts # <1024px (full-width) app-note-view/ ├── app-note-view.component.ts ├── app-note-view.desktop.component.ts # ≥1024px (3 colonnes + ToC) └── app-note-view.mobile.component.ts # <1024px (full-width + ToC inline) app-toc-drawer/ ├── app-toc-drawer.component.ts ├── app-toc-drawer.desktop.component.ts # ≥1024px (Fixed right) └── app-toc-drawer.mobile.component.ts # <1024px (Collapsible, inline) ``` ### Détection et Injection ```typescript // app-left-sidebar.component.ts import { Component, inject } from '@angular/core'; import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'; @Component({ selector: 'app-left-sidebar', standalone: true, template: ` @if (isDesktop$ | async) { } @else { } `, }) export class AppLeftSidebarComponent { private breakpoint = inject(BreakpointObserver); isDesktop$ = this.breakpoint.observe(Breakpoints.Large).pipe( map(result => result.matches) ); } ``` --- ## 📱 Navigation Mobile Avancée ### Tab/Drawer Navigation ```typescript // src/shared/services/mobile-nav.service.ts @Injectable({ providedIn: 'root' }) export class MobileNavService { activeTab = signal<'sidebar' | 'list' | 'page' | 'toc'>('list'); setTab(tab: 'sidebar' | 'list' | 'page' | 'toc') { this.activeTab.set(tab); // Persist if needed } } // Usage in component ``` ### Swipe Navigation (Gestures) ```typescript // Directive pour détection de swipe import { Directive, Output, EventEmitter, HostListener } from '@angular/core'; @Directive({ selector: '[appSwipeNav]', standalone: true, }) export class SwipeNavDirective { @Output() swipeLeft = new EventEmitter(); @Output() swipeRight = new EventEmitter(); private startX = 0; @HostListener('touchstart', ['$event']) onTouchStart(e: TouchEvent) { this.startX = e.touches[0].clientX; } @HostListener('touchend', ['$event']) onTouchEnd(e: TouchEvent) { const endX = e.changedTouches[0].clientX; const diff = this.startX - endX; if (Math.abs(diff) > 50) { // Seuil minimum if (diff > 0) this.swipeLeft.emit(); else this.swipeRight.emit(); } } } ``` --- ## 🎨 Composants Spécifiques (Mobile-First) ### 1) Bottom Navigation (Mobile) ```html ``` ### 2) Drawer Sidebar (Mobile) ```html
``` ### 3) Search Bar Compact (Mobile) ```html
{{ badge }} ✕
``` ### 4) Result List Item (Mobile-Optimized) ```html

{{ item.title }}

{{ item.modified | date:'short' }}
{{ tag }}

{{ item.excerpt }}

``` ### 5) Markdown Viewer (Mobile-Responsive) ```html
``` ### 6) ToC Drawer (Desktop Fixed, Mobile Inline) ```typescript // app-toc-drawer.component.ts @Component({ selector: 'app-toc-drawer', template: `
`, animations: [ trigger('slideDown', [ state('in', style({ height: '*' })), state('out', style({ height: '0px' })), transition('in <=> out', animate('200ms ease-in-out')), ]), ], standalone: true, }) export class AppTocDrawerComponent { @Input() headings: Heading[] = []; showTocMobile = false; isMobile$ = this.breakpoint.observe('(max-width: 1023px)').pipe( map(r => r.matches) ); } ``` --- ## 🎯 Livrables Attendus ### Code 1. **Toggle UI** : `UiModeService`, bouton navbar, `AppShellAdaptiveComponent` 2. **Responsive Wrappers** : Variants pour chaque composant (Desktop/Mobile), intégrant les patterns Nimbus 3. **Mobile Components** : Bottom nav, drawer sidebar, inline ToC, mobile search 4. **Gesture Handling** : Swipe navigation directive, touch-friendly interactions 5. **Breakpoint Utilities** : Service CDK layout, reactive signals ### Styling 1. **Tailwind Config** : Breakpoints personnalisés, tokens clair/sombre 2. **Mobile-First CSS** : Base mobile, enrichissements desktop via `md:`, `lg:` 3. **Touch-Friendly** : Boutons ≥44x44px, padding adéquat, hover states remplacés par tap sur mobile ### Documentation 1. **README_UI.md** : Schémas responsive, breakpoints, guide toggle, intégration Nimbus 2. **MOBILE_GUIDE.md** : Navigation gestures, bottom nav flow, drawer patterns 3. **RESPONSIVE_CHECKLIST.md** : Tests par breakpoint, checklist A11y mobile ### Tests 1. **E2E** : Toggle persistence, layout switch, gesture navigation 2. **Visual Regression** : Screenshots desktop/tablet/mobile 3. **Accessibility** : Touch targets, ARIA labels, keyboard nav (Tab key) --- ## ⚡ Performance & Mobile Optimizations ### Critical Optimizations - **Lazy-load images** : `loading="lazy"`, responsive `srcset` - **Virtual scroll** : CDK virtual scroll adapté mobile (item height ≈ 70–80px) - **Debounce search** : 300ms sur mobile, 150ms sur desktop - **Avoid layout shift** : Aspect ratios, skeleton loaders - **Network awareness** : `navigator.connection.effectiveType` pour adapt qualité - **Battery saver** : Réduire animations, throttle updates en mode saver ### Lighthouse Mobile Targets - Performance ≥ 85 - Accessibility ≥ 95 - Best Practices ≥ 90 --- ## 🎮 Raccourcis Clavier & Gestures ### Desktop - `Ctrl/Cmd + K` : Palette commandes - `Ctrl/Cmd + F` : Focus recherche - `[` `]` : Replier/ouvrir ToC - `Alt + ←/→` : Navigation historique ### Mobile/Tablet - **Tap** : Ouvrir note/item - **Swipe left/right** : Changer onglet (list → page → sidebar) - **Long-press** : Menu contextuel (favoris, open in new tab) - **Pull-to-refresh** : Rafraîchir liste (optionnel) - **Double-tap** : Zoom ToC (mobile) --- ## 📋 Critères d'Acceptation ### Desktop (≥1024px) - [x] Layout 3 colonnes (sidebar fixe/resizable, liste, page+ToC), fidèle à Nimbus - [x] Changement dossier/tag/tri reflété en URL - [x] 1000+ items fluide (60fps virtual scroll) - [x] ToC synchronisé + repliable - [x] Tous les flux clavier-seuls possibles ### Tablet (768–1023px) - [x] Navigation par onglets (Sidebar / List / Page) - [x] Drawer sidebar (80vw, swipeable) - [x] Bottom navigation sticky (4 icônes) - [x] Contenu full-width par onglet - [x] ToC inline collapsible ### Mobile (<768px) - [x] Drawer sidebar (80vw max) - [x] Bottom nav (4 onglets) - [x] Search bar compact (menu + search + filters) - [x] List items optimisés (titre + date + excerpt) - [x] Markdown full-screen - [x] ToC overlay ou inline toggle - [x] Touch targets ≥ 44x44px ### Feature Flag - [x] Toggle UI visible dans navbar - [x] État persisté (localStorage) - [x] Pas de perte d'état lors du switch - [x] Legacy UI reste intacte ### Accessibility - [x] WCAG 2.1 AA sur tous les breakpoints - [x] Keyboard navigation complète (Tab, Arrow, Enter) - [x] ARIA labels pour navigation tactile - [x] Focus visible partout - [x] Zoom ≤ 200% sans horizontal scroll ### Performance - [x] TTI < 2.5s cold start - [x] Scroll 60fps sur 1000+ items - [x] Lighthouse Mobile ≥ 85 perf, ≥ 95 a11y - [x] ImageOptimizations (lazy, srcset, format next-gen) --- ## 🗂️ Arborescence Fichiers ``` src/app/ ├── layout/ │ ├── app-shell-adaptive/ │ │ └── app-shell-adaptive.component.ts # Feature flag wrapper │ ├── app-shell-nimbus/ │ │ ├── app-shell-nimbus.component.ts # 3 colonnes (desktop) │ │ ├── app-shell-nimbus.desktop.component.ts │ │ └── app-shell-nimbus.mobile.component.ts │ └── app-navbar/ │ ├── app-navbar.component.ts │ └── [Bouton toggle UI intégré] │ ├── features/ │ ├── sidebar/ │ │ ├── app-left-sidebar.component.ts │ │ ├── app-left-sidebar.desktop.component.ts │ │ └── app-left-sidebar.mobile.component.ts │ │ │ ├── search-bar/ │ │ ├── app-search-bar.component.ts │ │ ├── app-search-bar.desktop.component.ts │ │ └── app-search-bar.mobile.component.ts │ │ │ ├── result-list/ │ │ ├── app-result-list.component.ts │ │ ├── app-result-list.desktop.component.ts │ │ ├── app-result-list.mobile.component.ts │ │ └── app-result-list-item.component.ts │ │ │ ├── note-view/ │ │ ├── app-note-view.component.ts │ │ ├── app-note-view.desktop.component.ts │ │ └── app-note-view.mobile.component.ts │ │ │ ├── toc-drawer/ │ │ ├── app-toc-drawer.component.ts │ │ └── app-toc-content.component.ts │ │ │ └── bottom-nav/ [NEW] │ ├── app-bottom-nav.component.ts │ └── app-bottom-nav.component.html │ ├── shared/ │ ├── services/ │ │ ├── ui-mode.service.ts # [NEW] Toggle management │ │ ├── mobile-nav.service.ts # [NEW] Tab/drawer state │ │ └── breakpoint.service.ts # [NEW] Responsive helper │ │ │ ├── directives/ │ │ └── swipe-nav.directive.ts # [NEW] Gesture detection │ │ │ └── components/ │ └── resizable-handle/ │ └── styles/ ├── tokens.css # Tailwind tokens ├── responsive.css # Breakpoint utilities └── mobile.css # Mobile-specific (touches, etc.) ``` --- ## 📅 Plan d'Implémentation (ordre conseillé) 1. **Feature Flag Infrastructure** (1-2j) - `UiModeService` + localStorage persistence - `AppShellAdaptiveComponent` wrapper - Toggle button dans navbar 2. **Responsive Shell & Breakpoints** (2-3j) - Desktop layout 3 colonnes (>=1024px) - Tailwind breakpoints & tokens - Resizable sidebar logic 3. **Mobile Navigation & Bottom Nav** (2-3j) - `BottomNavComponent` (4 onglets) - `MobileNavService` (state management) - Tab/drawer routing 4. **Mobile Sidebar Drawer** (1-2j) - Drawer animé (translate, backdrop) - Swipe dismiss directive - Z-index management 5. **Responsive Components** (3-4j) - Search bar variants (desktop/mobile) - Result list item responsive - Markdown viewer mobile optimizations 6. **ToC Drawer Adaptive** (1-2j) - Fixed right panel (desktop) - Inline toggle (mobile) - Animations smooth 7. **Gestures & Touch** (1-2j) - Swipe nav directive - Long-press menu - Pull-to-refresh (optionnel) 8. **Accessibility & Testing** (2-3j) - WCAG 2.1 AA audit - Keyboard nav (Tab, Arrow) - E2E tests (toggle, breakpoints, gestures) - Visual regression (3 breakpoints) **Total estimé** : 13–21 jours (équipe 1 FE engineer) --- ## 🚀 Scripts NPM ```bash # Dev complet (Nimbus activé par défaut) npm run dev # Build production npm run build # Tests responsifs (plusieurs breakpoints) npm run test:responsive # Lighthouse audit mobile npm run audit:lighthouse:mobile # Feature flag (override) NIMBUS_UI=false npm run dev # Force legacy UI ``` --- ## ✅ Checklist Livraison - [ ] Toggle UI visible, fonctionnel, persisté - [ ] Desktop (≥1024px) : 3 colonnes, interactions fluides - [ ] Tablet (768–1023px) : Onglets + drawer, full-width contenu - [ ] Mobile (<768px) : Bottom nav, drawer, touch-friendly - [ ] Tous les flux clavier-seuls réalisables - [ ] Lighthouse mobile ≥ 85 perf, ≥ 95 a11y - [ ] Virtual scroll 60fps sur 1000+ items - [ ] Tests E2E (toggle, breakpoints, gestures) - [ ] Documentation complète (README_UI.md, MOBILE_GUIDE.md, RESPONSIVE_CHECKLIST.md) - [ ] Zéro régression : legacy UI inchangée, Wikilinks, bookmarks, graph intacts - [ ] Screenshots before/after 3 breakpoints - [ ] Fidélité 100% à la description Nimbus (chips, pickers, outline, etc.) --- ## 📖 Documentation à Produire 1. **README_UI.md** : Overview, architecture, screenshots 3 breakpoints 2. **MOBILE_GUIDE.md** : Navigation onglets, gestures, drawer patterns 3. **RESPONSIVE_CHECKLIST.md** : Tests par breakpoint, device testing 4. **DEPLOYMENT.md** : Feature flag pour bascule progressive 5. **ARCHITECTURE_DIAGRAM.md** : Schémas adaptatifs (Mermaid) --- ## 💡 Notes Importantes - **Mobile First** : Développer pour mobile en premier, puis enrichir desktop. - **Persistent State** : Le toggle UI et les filtres actifs doivent persister via localStorage (sans browser storage, utiliser sessionStorage ou service state). - **Zero Regression** : L'ancienne interface reste intacte et fonctionnelle. - **Performance** : Virtual scroll adapté mobile (40+ items à l'écran), lazy-load images. - **Accessibility** : 44x44px touch targets minimum, ARIA labels complets, keyboard nav. - **Testing** : Visual regression sur breakpoints clés (375px / 768px / 1440px). - **Intégration Nimbus** : Tous les éléments de la description (philosophie, layouts, micro-interactions) doivent être reproduits fidèlement, avec adaptations responsives pour mobile/tablette (ex. hover-reveal → tap-reveal). --- **Exécute maintenant ce plan** : crée les composants, adapte les routes/états, ajoute les styles Tailwind responsifs, branche la recherche et livre le MR conforme aux critères ci-dessus avec toggle UI et compatibilité 100% Desktop/Mobile.