# π― Prompt Windsurf β ObsiViewer Nimbus UI (Desktop + Mobile)
## ObsiViewer β Interface "Nimbus-like" 100% Responsive
**RΓ΄le & mode :** Agis comme **Staff Frontend Engineer Angular 20 + UX Designer** expert. 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** (Desktop + Mobile + Tablet). Un **bouton toggle** dans la navbar permet de basculer entre l'ancienne interface et la nouvelle sans perte d'Γ©tat.
---
## Contexte
* **Projet** : ObsiViewer (Angular 20 + Tailwind, Node/Express backend)
* **Objectif** : Refondre l'interface selon un design **Nimbus Notes/FuseBase**-like avec responsive design complet
* **CΕurs d'usage** : navigation par **dossiers**, **tags**, **recherche**, **lecture markdown** plein Γ©cran, **ToC** Γ  droite, **tri et filtres** rapides[1][2][3]
* **NouveautΓ©** : Design adaptatif complet (Desktop/Mobile/Tablet) avec UI toggle persistΓ©
***
## π― Architecture Responsive Cible
### Desktop (β₯1024px) - Layout 3 Colonnes
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NAVBAR (Dark, fixed, h-14) + Toggle UI                 β
ββββββββββββββββββ¬βββββββββββββββββββ¬βββββββββββββββββββββββ€
β                β                  β                      β
β  SIDEBAR       β   RESULT LIST    β   NOTE VIEW + TOC    β
β  (240-440px)   β   (virtualized)  β   (Resizable)        β
β  Resizable     β                  β                      β
β                β                  β                      β
β  - Quick Links β  - Search bar    β  - Markdown          β
β  - Folders     β  - Chips filters β  - ToC drawer        β  
β  - Tags        β  - Items (80px)  β  - Actions bar       β
β                β  - Pagination    β                      β
β                β                  β                      β
ββββββββββββββββββ΄βββββββββββββββββββ΄βββββββββββββββββββββββ
```
### Mobile (<768px) - Navigation par Onglets
```
ββββββββββββββββββββββββββββββββββββ
β NAVBAR (compact, h-12)           β
β [β‘] [Search] [Toggle]            β
ββββββββββββββββββββββββββββββββββββ€
β                                  β
β  CONTENT AREA (Full-width)       β
β  - Drawer sidebar (80vw gauche)  β
β  - Liste swipeable (tab liste)   β  
β  - Markdown full-screen (page)   β
β  - ToC inline (toggle button)    β
β                                  β
ββββββββββββββββββββββββββββββββββββ€
β BOTTOM NAVIGATION (sticky)       β  
β [π] [π] [π] [π] (4 onglets)  β
ββββββββββββββββββββββββββββββββββββ
```
### Tablet (768px β€ width < 1024px) - Hybride
```
ββββββββββββββββββββββββββββββββββββββββ
β NAVBAR + Toggle (fixed, h-14)        β
ββββββββββββββββββββββββββββββββββββββββ€
β  TAB NAVIGATION (3 onglets)          β
β  [Sidebar] [List] [Page]             β
ββββββββββββββββββββββββββββββββββββββββ€
β                                      β
β  ACTIVE TAB CONTENT (scrollable)     β
β  - Panneau full-width par tab        β  
β  - Drawer si besoin                  β
β                                      β
ββββββββββββββββββββββββββββββββββββββββ
```
***
## π Architecture Feature Flag & Toggle
### 1) Toggle UI dans la NavBar
Ajouter un **bouton toggle** dans `src/app/layout/app-navbar/app-navbar.component.ts` :[4]
```html
  
  
```
### 2) Service de Gestion du Mode UI
CrΓ©er `src/app/shared/services/ui-mode.service.ts` :
```typescript
import { Injectable, signal, effect } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class UiModeService {
  // Signal pour rΓ©activitΓ© fine-grained[3]
  isNimbusMode = signal(this.loadUIMode());
  constructor() {
    // Persister les changements automatiquement
    effect(() => {
      if (typeof localStorage !== 'undefined') {
        localStorage.setItem('obsiviewer-ui-mode', 
          this.isNimbusMode() ? 'nimbus' : 'legacy');
      }
    });
  }
  toggleUIMode() {
    const newMode = !this.isNimbusMode();
    this.isNimbusMode.set(newMode);
  }
  private loadUIMode(): boolean {
    if (typeof localStorage === 'undefined') return true;
    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 (Mobile-First)[5][6]
```javascript
// 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
    },
    extend: {
      // Tokens personnalisΓ©s Nimbus-like
      colors: {
        nimbus: {
          50: '#f0f9ff',
          500: '#0ea5e9', // Turquoise actions
          900: '#0c4a6e'  // Dark mode
        }
      }
    }
  },
};
```
### Service de DΓ©tection Responsive
```typescript
// src/shared/services/breakpoint.service.ts
import { Injectable, signal, inject } from '@angular/core';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { map } from 'rxjs/operators';
@Injectable({ providedIn: 'root' })
export class ResponsiveService {
  private breakpointObserver = inject(BreakpointObserver);
  
  // Signaux rΓ©actifs pour chaque breakpoint[25][28]
  isMobile = signal(false);
  isTablet = signal(false);
  isDesktop = signal(false);
  
  constructor() {
    // Mobile (< 768px)
    this.breakpointObserver.observe('(max-width: 767px)').subscribe(result => {
      this.isMobile.set(result.matches);
    });
    
    // Tablet (768px - 1023px)
    this.breakpointObserver.observe('(min-width: 768px) and (max-width: 1023px)').subscribe(result => {
      this.isTablet.set(result.matches);
    });
    
    // Desktop (>= 1024px)
    this.breakpointObserver.observe('(min-width: 1024px)').subscribe(result => {
      this.isDesktop.set(result.matches);
    });
  }
}
```
***
## π± Composants Responsifs SpΓ©cifiques
### 1) Shell Principal Nimbus (Responsive)
```typescript
// app-shell-nimbus.component.ts
import { Component, inject } from '@angular/core';
import { ResponsiveService } from '@app/shared/services/responsive.service';
@Component({
  selector: 'app-shell-nimbus-layout',
  template: `
    
    
    
    
      
    
  `,
  standalone: true,
  imports: [/* tous les composants */],
})
export class AppShellNimbusLayoutComponent {
  responsive = inject(ResponsiveService);
}
```
### 2) Bottom Navigation Mobile
```typescript
// app-bottom-navigation.component.ts
import { Component, inject } from '@angular/core';
import { MobileNavService } from '@app/shared/services/mobile-nav.service';
@Component({
  selector: 'app-bottom-navigation',
  template: `
    
  `,
  standalone: true,
})
export class AppBottomNavigationComponent {
  mobileNav = inject(MobileNavService);
  
  tabs = [
    { id: 'sidebar', icon: 'π', label: 'Dossiers' },
    { id: 'list', icon: 'π', label: 'Liste' },  
    { id: 'page', icon: 'π', label: 'Page' },
    { id: 'toc', icon: 'π', label: 'Sommaire' }
  ];
  setActiveTab(tabId: string) {
    this.mobileNav.setActiveTab(tabId as any);
  }
}
```
### 3) Service Navigation Mobile
```typescript
// src/shared/services/mobile-nav.service.ts
import { Injectable, signal } from '@angular/core';
type MobileTab = 'sidebar' | 'list' | 'page' | 'toc';
@Injectable({ providedIn: 'root' })
export class MobileNavService {
  activeTab = signal('list');
  
  // Γtat des drawers
  sidebarOpen = signal(false);
  tocOpen = signal(false);
  
  setActiveTab(tab: MobileTab) {
    this.activeTab.set(tab);
    
    // Auto-fermer les drawers quand on change d'onglet
    if (tab !== 'sidebar') this.sidebarOpen.set(false);
    if (tab !== 'toc') this.tocOpen.set(false);
  }
  
  toggleSidebar() {
    this.sidebarOpen.update(open => !open);
  }
  
  toggleToc() {
    this.tocOpen.update(open => !open);
  }
}
```
### 4) Drawer Sidebar Mobile
```typescript
// app-sidebar-drawer.component.ts
import { Component, inject } from '@angular/core';
import { MobileNavService } from '@app/shared/services/mobile-nav.service';
@Component({
  selector: 'app-sidebar-drawer',
  template: `
    
    
    
    
  `,
  standalone: true,
  imports: [AppSidebarContentComponent],
})
export class AppSidebarDrawerComponent {
  mobileNav = inject(MobileNavService);
}
```
### 5) Search Bar Responsive
```typescript
// app-search-bar.component.ts
import { Component, inject } from '@angular/core';
import { ResponsiveService } from '@app/shared/services/responsive.service';
import { MobileNavService } from '@app/shared/services/mobile-nav.service';
@Component({
  selector: 'app-search-bar',
  template: `
    
    
    
    
  `,
  standalone: true,
})
export class AppSearchBarComponent {
  responsive = inject(ResponsiveService);
  mobileNav = inject(MobileNavService);
  
  searchQuery = '';
  activeFilters: string[] = [];
  openFilters() { /* */ }
  removeFilter(filter: string) { /* */ }
  openFolderPicker() { /* */ }
  openTagPicker() { /* */ }
  openPagePicker() { /* */ }
}
```
### 6) Liste de RΓ©sultats Responsive
```typescript
// app-result-list.component.ts
import { Component, inject, Input } from '@angular/core';
import { ResponsiveService } from '@app/shared/services/responsive.service';
@Component({
  selector: 'app-result-list',
  template: `
    
    dk-virtual-scroll-viewport 
      [itemSize]="responsive.isMobile() ? 70 : 80" 
      class="h"h-full">
      
      
      
      
    
  `,
  standalone: true,
  imports: [ScrollingModule],
})
export class AppResultListComponent {
  responsive = inject(ResponsiveService);
  
  @Input() items: any[] = [];
  
  trackByFn(index: number, item: any) {
    return item.id;
  }
  
  openNote(item: any) {
    // Navigation vers la note
  }
}
```
### 7) Item de RΓ©sultat Mobile-Optimized
```typescript
// app-result-list-item.component.ts  
@Component({
  selector: 'app-result-list-item',
  template: `
    
      
      
      
        {{ item.title }}
      
      
      
      
        {{ item.modified | date:'short' }}
        
          
            {{ tag }}
          
        
       
      
      
      
        {{ item.excerpt }}
      
     
  `,
  standalone: true,
})
export class AppResultListItemComponent {
  @Input() item: any;
  @Input() compact = false;
}
```
### 8) Markdown Viewer avec ToC Responsive
```typescript
// app-markdown-viewer.component.ts
import { Component, inject } from '@angular/core';
import { ResponsiveService } from '@app/shared/services/responsive.service';
import { MobileNavService } from '@app/shared/services/mobile-nav.service';
@Component({
  selector: 'app-markdown-viewer',
  template: `
    
    
      
      
      
        {{ currentNote?.title }}
        
        
          
          
          
          
          
            
            
            
          
         
       
      
      
      
        
      
      
     
    
     0"
                   [headings]="headings"
                   class="fixed right-0 top-14 bottom-0 w-64 
                          bg-gray-50 dark:bg-gray-800 border-l 
                          border-gray-200 dark:border-gray-700">
    
    
    
    
  `,
  standalone: true,
})
export class AppMarkdownViewerComponent {
  responsive = inject(ResponsiveService);
  mobileNav = inject(MobileNavService);
  
  @Input() currentNote: any;
  @Input() markdownHTML = '';
  @Input() headings: any[] = [];
}
```
***
## π¬ Gestures & Navigation Tactile
### Directive Swipe Navigation
```typescript
// src/shared/directives/swipe-nav.directive.ts
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;
  private startY = 0;
  private threshold = 50; // Minimum distance
  private restraint = 100; // Maximum perpendicular distance
  @HostListener('touchstart', ['$event'])
  onTouchStart(e: TouchEvent) {
    const touch = e.touches[0];
    this.startX = touch.clientX;
    this.startY = touch.clientY;
  }
  @HostListener('touchend', ['$event'])
  onTouchEnd(e: TouchEvent) {
    const touch = e.changedTouches[0];
    const endX = touch.clientX;
    const endY = touch.clientY;
    
    const distX = this.startX - endX;
    const distY = Math.abs(this.startY - endY);
    
    // VΓ©rifier que c'est bien un swipe horizontal
    if (Math.abs(distX) >= this.threshold && distY <= this.restraint) {
      if (distX > 0) {
        this.swipeLeft.emit();
      } else {
        this.swipeRight.emit();
      }
    }
  }
}
```
### Usage Mobile avec Swipe
```html
```
***
## β‘ Performance & Optimisations Mobile
### Critical Optimizations[7][8]
```typescript
// Lazy loading des images
// app-image-lazy.directive.ts
@Directive({
  selector: 'img[appLazyLoad]'
})
export class LazyLoadDirective implements OnInit {
  @Input() src!: string;
  @Input() alt = '';
  
  ngOnInit() {
    const observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const img = entry.target as HTMLImageElement;
          img.src = this.src;
          img.alt = this.alt;
          observer.unobserve(img);
        }
      });
    });
    
    observer.observe(this.el.nativeElement);
  }
}
```
### Skeleton Loaders Mobile
```typescript
// app-skeleton.component.ts
@Component({
  selector: 'app-skeleton',
  template: `
    
  `,
  standalone: true,
})
export class AppSkeletonComponent {
  responsive = inject(ResponsiveService);
}
```
***
## π
 Plan d'ImplΓ©mentation PriorisΓ©
### Phase 1: Infrastructure (2-3j)
- β
 `UiModeService` + localStorage persistence
- β
 `ResponsiveService` avec BreakpointObserver[9][10]
- β
 `AppShellAdaptiveComponent` wrapper
- β
 Toggle button dans navbar
- β
 Breakpoints Tailwind mobile-first[6][5]
### Phase 2: Layout Desktop (3-4j)
- β
 Desktop layout 3 colonnes (β₯1024px)
- β
 Sidebar resizable avec dossiers/tags
- β
 Liste virtualisΓ©e performante
- β
 ToC panel fixe Γ  droite
- β
 Search bar avec chips de filtres[2][1]
### Phase 3: Navigation Mobile (2-3j)  
- β
 `MobileNavService` (state management)
- β
 `BottomNavigationComponent` (4 onglets)[11][12]
- β
 Tab routing et state persistence
- β
 Swipe gestures directive[13][14]
### Phase 4: Composants Mobile (3-4j)
- β
 Drawer sidebar mobile[15][16]
- β
 Search bar responsive compacte
- β
 Result list item mobile-optimized
- β
 Markdown viewer full-screen mobile
- β
 ToC overlay mobile avec animations
### Phase 5: Tablet & Transitions (1-2j)
- β
 Layout hybride tablet (768-1023px)
- β
 Animations fluides entre breakpoints
- β
 Touch targets β₯ 44px[6]
- β
 Gesture handling avancΓ©
### Phase 6: Testing & Polish (2-3j)
- β
 Tests E2E (toggle, breakpoints, gestures)
- β
 Lighthouse mobile audit (β₯85 perf, β₯95 a11y)
- β
 Visual regression (3 breakpoints)
- β
 Keyboard navigation complète
- β
 WCAG 2.1 AA compliance
**Total estimΓ©** : 13-19 jours (Γ©quipe 1 FE engineer)
***
## ποΈ Structure des Fichiers
```
src/app/
βββ layout/
β   βββ app-shell-adaptive/
β   β   βββ app-shell-adaptive.component.ts      # Feature flag wrapper
β   βββ app-shell-nimbus/
β   β   βββ app-shell-nimbus.component.ts        # Layout responsive
β   β   βββ app-shell-nimbus.desktop.html        # Template desktop  
β   β   βββ app-shell-nimbus.tablet.html         # Template tablet
β   β   βββ app-shell-nimbus.mobile.html         # Template mobile
β   βββ app-navbar/
β       βββ app-navbar.component.ts
β       βββ app-navbar.desktop.html              # NavBar desktop
β       βββ app-navbar.mobile.html               # NavBar mobile compact
β
βββ features/
β   βββ sidebar/
β   β   βββ app-left-sidebar.component.ts        # Desktop sidebar
β   β   βββ app-sidebar-drawer.component.ts      # Mobile drawer[39]
β   β   βββ app-sidebar-content.component.ts     # Contenu partagΓ©
β   β
β   βββ search-bar/
β   β   βββ app-search-bar.component.ts          # Responsive wrapper
β   β   βββ app-search-desktop.component.ts      # Desktop full
β   β   βββ app-search-mobile.component.ts       # Mobile compact
β   β
β   βββ result-list/
β   β   βββ app-result-list.component.ts         # Liste virtualisΓ©e
β   β   βββ app-result-list-item.component.ts    # Item responsive
β   β
β   βββ note-view/
β   β   βββ app-markdown-viewer.component.ts     # Viewer responsive
β   β   βββ app-toc-panel.component.ts           # ToC desktop fixe
β   β   βββ app-toc-overlay.component.ts         # ToC mobile overlay
β   β
β   βββ bottom-nav/ [NEW]
β   β   βββ app-bottom-navigation.component.ts   # Navigation mobile[40]
β   β   βββ app-tab-navigation.component.ts      # Navigation tablet
β   β
β   βββ mobile-content/ [NEW]
β       βββ app-mobile-content.component.ts      # Container mobile
β       βββ app-tab-content.component.ts         # Container tablet
β
βββ shared/
β   βββ services/
β   β   βββ ui-mode.service.ts                   # Toggle UI management
β   β   βββ responsive.service.ts                # Breakpoint detection[25]
β   β   βββ mobile-nav.service.ts                # Tab/drawer state mobile
β   β
β   βββ directives/
β   β   βββ swipe-nav.directive.ts               # Gesture detection[41]
β   β   βββ lazy-load.directive.ts               # Image lazy loading
β   β
β   βββ components/
β       βββ skeleton/
β       β   βββ app-skeleton.component.ts        # Loading states
β       βββ filter-chip/
β           βββ app-filter-chip.component.ts     # Chips rΓ©utilisables[1]
β
βββ styles/
    βββ tokens.scss                              # Variables Nimbus
    βββ responsive.scss                          # Utilitaires responsive[21]
    βββ mobile.scss                              # Styles mobile-specific
    βββ animations.scss                          # Transitions smooth
```
***
## β
 Critères d'Acceptation
### β
 Desktop (β₯1024px)
- Layout 3 colonnes (sidebar fixe/resizable, liste, page+ToC)[1][2]
- Changement dossier/tag/tri reflΓ©tΓ© en URL
- 1000+ items fluide (60fps virtual scroll)
- ToC synchronisΓ© + repliable cΓ΄tΓ© droit
- Navigation clavier-seule possible partout
### β
 Mobile (<768px)  
- Drawer sidebar (80vw max) avec backdrop[16][15]
- Bottom nav (4 onglets) sticky[12][11]
- Search bar compact (menu + search + filters)
- List items optimisΓ©s (titre + date + excerpt)
- Markdown full-screen avec ToC overlay
- Touch targets β₯ 44x44px[6]
- Swipe navigation entre onglets[13]
### β
 Tablet (768-1023px)
- Navigation par 3 onglets principaux  
- Contenu full-width par tab
- Drawer optionnel selon besoin
- Bottom navigation hybride
### β
 Feature Flag
- Toggle UI visible dans navbar
- Γtat persistΓ© (localStorage)  
- Pas de perte d'Γ©tat lors du switch
- Legacy UI reste intacte et fonctionnelle
### β
 Performance & AccessibilitΓ©
- TTI < 2.5s cold start
- Scroll 60fps sur 1000+ items
- Lighthouse Mobile β₯ 85 perf, β₯ 95 a11y[8][7]
- WCAG 2.1 AA sur tous les breakpoints
- Keyboard navigation complète (Tab, Arrow, Enter)
- Focus visible partout, zoom β€ 200% sans scroll horizontal
***
## π Scripts & Commandes
```bash
# Dev complet (Nimbus activΓ© par dΓ©faut)
npm run dev
# Build production avec optimisations mobile
npm run build:mobile
# 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
NIMBUS_UI=true npm run dev         # Force Nimbus UI
# Screenshots responsive pour tests visuels
npm run screenshot:all-breakpoints
```
***
## π Documentation Γ  Produire
1. **README_UI_RESPONSIVE.md** : Architecture, breakpoints, captures d'Γ©cran 3 formats
2. **MOBILE_GUIDE.md** : Navigation onglets, gestures, patterns drawer
3. **RESPONSIVE_CHECKLIST.md** : Tests par breakpoint, device testing
4. **DEPLOYMENT_PROGRESSIVE.md** : Feature flag pour migration douce
5. **PERFORMANCE_MOBILE.md** : Optimisations, lazy loading, metrics
***
## π‘ Notes Cruciales
- **Mobile First Absolu** : DΓ©velopper mobile d'abord, puis enrichir tablet/desktop[5][6]
- **Zero Regression** : L'interface legacy reste 100% intacte et fonctionnelle
- **Γtat Persistant** : Toggle UI, filtres actifs, tab mobile via localStorage  
- **Performance** : Virtual scroll adaptΓ© mobile, lazy-load images, skeleton loaders[7]
- **Accessibility** : 44px touch targets, ARIA labels complets, keyboard nav[6]
- **Testing** : Visual regression sur 3 breakpoints clΓ©s (375px/768px/1440px)
- **Gestures** : Swipe navigation fluide, long-press menus, pull-to-refresh optionnel[14][13]
***
**Exécute maintenant ce plan complet** : crée tous les composants responsifs, implémente les services de state management, configure les breakpoints Tailwind mobile-first, branche la navigation tactile avec gestures, et livre le MR conforme aux critères ci-dessus avec toggle UI et compatibilité 100% Desktop/Tablet/Mobile.[5][13]
[1](https://nimbuslearning.com/team_member/aaron-lee/)
[2](https://thefusebase.com/guides/android-ios/mobile-apps/)
[3](https://thefusebase.com/guides/getting-started/structure-in-nimbus-note/)
[4](https://blog.angular-university.io/angular-responsive-design/)
[5](https://tailwindcss.com/docs/responsive-design)
[6](https://dev.to/hitesh_developer/20-tips-for-designing-mobile-first-with-tailwind-css-36km)
[7](https://www.youtube.com/watch?v=S2eyA3zk0BQ)
[8](https://www.linkedin.com/pulse/designing-responsive-uis-angular-mobile-first-adaptive-yeturi-sx1wc)
[9](https://material.angular.dev/cdk/layout/overview)
[10](https://www.thisdot.co/blog/how-to-manage-breakpoints-using-breakpointobserver-in-angular)
[11](https://m2.material.io/components/bottom-navigation)
[12](https://www.infragistics.com/products/ignite-ui-angular/angular/components/tabbar)
[13](https://stackoverflow.com/questions/42592156/what-is-the-best-way-to-implement-swipe-navigation-in-angular-2)
[14](https://js.devexpress.com/Angular/Documentation/Guide/UI_Components/List/End-User_Interaction/Touch-Screen_Gestures/)
[15](https://material.angular.dev/components/sidenav/overview)
[16](https://dev.to/davidihl/how-to-create-a-responsive-sidebar-and-mini-navigation-with-material-angular-o5l)
[17](https://smart-interface-design-patterns.com)
[18](https://www.reddit.com/r/angular/comments/1gjjkpt/responsive_design_best_practice/)
[19](https://smashingconf.com/online-workshops/workshops/interface-design-course-vitaly-friedman-spring/)
[20](https://www.youtube.com/watch?v=svetVZJewDk)
[21](https://blog.pixelfreestudio.com/how-to-implement-mobile-first-design-in-angular/)
[22](https://devoxsoftware.com/blog/improve-engagement-of-your-saas-with-ux-ui-design-best-practices/)
[23](https://appsumo.com/products/fusebase/questions/pavel-1430723/)
[24](https://thefusebase.com/note/)
[25](https://www.youtube.com/watch?v=bGoemPZfQzk)
[26](https://angular.love/responsive-angular-components)
[27](https://www.thedesignership.com/blog/the-ultimate-guide-to-ux-ui-design-in-2024)
[28](https://fivetaco.com/products/fusebase)
[29](https://help.luware.com/best-practices-category/best-practices-designing-messages-and-adaptive-cards-in-ms-teams)
[30](https://www.reddit.com/r/FlutterDev/comments/1alapqu/should_i_separate_the_codebase_for_desktop_and/)
[31](https://stackoverflow.com/questions/65782044/without-media-queries-how-to-achieve-3-column-desktop-to-1-column-mobile-layout)
[32](https://m2.material.io/design/layout/responsive-layout-grid.html)
[33](https://tailwindcss.com/plus/templates/pocket)
[34](https://www.w3schools.com/howto/howto_css_three_columns.asp)
[35](https://stackoverflow.com/questions/78141479/how-to-change-desktop-first-design-code-to-mobile-first-with-tailwind-css-respo)
[36](https://www.linkedin.com/posts/angular-material-dev_angular-angularmaterial-webdevelopment-activity-7354526847910445056-jqNb)
[37](https://stackoverflow.com/questions/72945583/breakpointobserver-angular)
[38](https://www.reddit.com/r/Frontend/comments/1fevx2e/anyone_switched_from_desktop_first_to_mobile/)
[39](https://teamtreehouse.com/community/three-column-layout-that-is-responsive)
[40](https://www.youtube.com/watch?v=I13uAoOGU_4)
[41](https://dev.to/slyskillet/mobile-first-design-with-tailwind-css-3phd)
[42](https://www.telerik.com/kendo-angular-ui/components/grid/styling-and-appearance/responsive-design)
[43](https://www.digitalocean.com/community/tutorials/angular-breakpoints-angular-cdk)
[44](https://www.bootstrapdash.com/blog/tailwind-responsive-design-tips)
[45](https://www.reddit.com/r/Angular2/comments/w0co1t/how_to_implement_gestures_swipe_left_slider_in_an/)
[46](https://www.youtube.com/watch?v=4CYuOiRHHA8)
[47](https://www.telerik.com/kendo-angular-ui/bottomnavigation)
[48](https://developer.mozilla.org/en-US/docs/Web/API/Touch_events)
[49](https://stackoverflow.com/questions/57885511/angular-material-nav-sidebar-only-shows-on-responsive-resizing)
[50](https://stackoverflow.com/questions/50445545/create-mobile-bottom-navigation-with-angular-material)
[51](https://material.angular.dev/components/sidenav)
[52](https://material.angular.dev/components/tabs/overview)
[53](https://30dayscoding.com/blog/angular-animations-and-gesture-support)
[54](https://stackoverflow.com/questions/63642803/angular-material-sidenav-rail-mode-hidden-on-mobile)
[55](https://demo.mobiscroll.com/angular/navigation/bottom-navigation)
[56](https://angular.love/gestures-in-an-angular-application)
[57](https://stackblitz.com/edit/angular-closing-side-nav-in-mobile?file=app%2Fsidenav-responsive-example.html)
[58](https://www.reddit.com/r/ionic/comments/1jwmsnr/iontabbar_and_transparent_device_navbar/)