Keep/_bmad-output/planning-artifacts/DESIGN-WIREFRAMES.md
sepehr ddb67ba9e5 fix: unify theme system - fix theme switching persistence
- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
2026-01-18 22:33:41 +01:00

46 KiB

🎨 WIREFRAMES - PROJET KEEP

Date: 2026-01-17
Responsable: John - Product Manager
Client: Ramez
Version: 1.0


📋 SOMMAIRE

  1. Page Notebook - Desktop
  2. Page Notebook - Mobile
  3. Page Admin
  4. Page Profil
  5. Composants UI Réutilisables
  6. Design System Unified

1. PAGE NOTEBOOK - DESKTOP

1.1 Vue d'ensemble

Dimensions : 1920x1080 (responsive jusqu'à 1280x720)
Layout : 3 colonnes (Sidebar gauche + Contenu central + (optionnel) Sidebar droite)

┌─────────────────────────────────────────────────────────────────────────────┐
│ HEADER GLOBAL (64px de hauteur)                                       │
│ [LOGO] [RECHERCHE LARGEUR 384px] [NOTIFS] [AVATAR]                │
├──────────────┬──────────────────────────────────────────────────────────────┤
│              │                                                      │
│ SIDEBAR      │ CONTENU PRINCIPAL                                    │
│ GAUCHE       │ (Masonry Grid - 3 colonnes)                           │
│ (256px)      │                                                      │
│              │                                                      │
│ [ICÔNE      │ ┌────────┐  ┌────────┐  ┌────────┐                │
│  NOTEBOOK]   │ │CARTE 1│  │CARTE 2│  │CARTE 3│                │
│              │ │Image  │  │Image  │  │Image  │                │
│ [PERSONAL]   │ │Titre  │  │Titre  │  │Titre  │                │
│              │ │Contenu│  │Contenu│  │Contenu│                │
│ [VOYAGE] ✅ │ │Labels │  │Labels │  │Labels │                │
│   ├─#Hôtels│ └────────┘  └────────┘  └────────┘                │
│   ├─#Vols   │                                                      │
│   ├─#Restos │ ┌────────┐  ┌────────┐  ┌────────┐                │
│   └─+[LABEL]│ │CARTE 4│  │CARTE 5│  │CARTE 6│                │
│              │ │Image  │  │Image  │  │Image  │                │
│ [WORK]       │ │Titre  │  │Titre  │  │Titre  │                │
│              │ │Contenu│  │Contenu│  │Contenu│                │
│ [IDEAS]     │ │Labels │  │Labels │  │Labels │                │
│              │ └────────┘  └────────┘  └────────┘                │
│ ──────────────┤                                                      │
│ SMART VIEWS  │ [NOTE CARD AU SURVOL]                                 │
│              │ ┌──────────────────────────────────────────────────┐     │
│ [⭐ FAVS]   │ │ [...]                                [EDITER] │     │
│ [✓ TÂCHES] │ │ ┌─────────────────────────────────────────┐│     │
│              │ │ │ Image Hero (60% hauteur)           ││     │
│              │ │ │ ┌─────────────────────────────────┐ ││     │
│ AI SUGGESTIONS│ │ │ │ Titre de la note                 │ ││     │
│ [💡 2 idées  │ │ │ │ ┌─────────────────────────────────┐│ ││     │
│   pour       │ │ │ │ │ Contenu de la note (2-3 lignes)││ ││     │
│   Voyage]    │ │ │ │ └─────────────────────────────────┘│ ││     │
│              │ │ │ └─────────────────────────────────┘ ││     │
│              │ │ │ [AVATAR]                    [DATE] │ ││     │
│              │ │ │ 🏷️ #Hôtels 🏷️ #Réservations    │ ││     │
│              │ │ └─────────────────────────────────────────┘│     │
│              │ └──────────────────────────────────────────────────┘     │
│              │                                                      │
│              │ [BOUTON FLOTTANT "AJOUTER NOTE" (FAB)]              │
│              │ (carrond, icône +, ombre)                       │
└──────────────┴──────────────────────────────────────────────────────────────┘

1.2 Spécifications détaillées

HEADER GLOBAL

<header className="h-16 flex items-center justify-between px-6 border-b bg-background z-20">
  {/* Logo */}
  <div className="flex items-center gap-3">
    <div className="size-8 bg-primary rounded-lg flex items-center justify-center">
      <StickyNote2Icon className="text-white" />
    </div>
    <h1 className="text-xl font-bold tracking-tight">KEEP</h1>
  </div>

  {/* Recherche */}
  <label className="hidden md:flex w-96">
    <div className="flex w-full h-10 rounded-xl bg-muted focus-within:ring-2">
      <SearchIcon className="muted-foreground ml-4" />
      <input 
        className="flex-1 bg-transparent px-3 text-sm focus:ring-0"
        placeholder="Rechercher notes, étiquettes..."
      />
    </div>
  </label>

  {/* Actions droite */}
  <div className="flex items-center gap-3">
    <Button variant="ghost" size="icon">
      <SettingsIcon />
    </Button>
    <Avatar className="size-10 ring-2 ring-background">
      <AvatarImage src={user.avatar} />
      <AvatarFallback>{user.initials}</AvatarFallback>
    </Avatar>
  </div>
</header>

SIDEBAR GAUCHE (256px)

<aside className="w-64 hidden md:flex flex-col border-r bg-background overflow-y-auto">
  <div className="p-4 flex flex-col gap-6">
    
    {/* Section Notebooks */}
    <div className="flex flex-col gap-2">
      <div className="flex items-center justify-between px-3 mb-2">
        <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground">
          Notebooks
        </h3>
        <Button variant="ghost" size="icon-sm">
          <AddIcon className="text-muted-foreground" />
        </Button>
      </div>

      {/* Notebook Personal (inactif) */}
      <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
        <BookIcon className="text-muted-foreground" />
        <span>Personal</span>
      </Button>

      {/* Notebook Voyage (actif - ouvert) */}
      <div className="flex flex-col rounded-lg overflow-hidden border-l-4 border-primary bg-primary/5">
        <div className="flex items-center justify-between px-3 py-2.5">
          <div className="flex items-center gap-3">
            <FlightTakeoffIcon className="text-primary" />
            <span className="font-bold text-primary">Voyage</span>
          </div>
          <ChevronDownIcon className="text-primary/60" />
        </div>
        
        {/* Labels contextuels imbriqués */}
        <div className="flex flex-col pb-2">
          <Button variant="ghost" className="justify-start gap-3 pl-10 pr-3 py-1.5">
            <LabelIcon className="text-primary/70" />
            <span className="text-xs font-medium">#Hôtels <span className="opacity-50">(3)</span></span>
          </Button>
          <Button variant="ghost" className="justify-start gap-3 pl-10 pr-3 py-1.5">
            <LabelIcon className="text-primary/70" />
            <span className="text-xs font-medium">#Vols</span>
          </Button>
          <Button variant="ghost" className="justify-start gap-3 pl-10 pr-3 py-1.5">
            <LabelIcon className="text-primary/70" />
            <span className="text-xs font-medium">#Restos</span>
          </Button>
          <Button variant="ghost" className="justify-start gap-2 pl-10 pr-3 py-1.5 text-primary hover:underline">
            <AddCircleIcon />
            <span className="text-xs font-bold">Labels</span>
          </Button>
        </div>
      </div>

      {/* Notebook Work (inactif) */}
      <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
        <WorkIcon className="text-muted-foreground" />
        <span>Work Projects</span>
      </Button>
    </div>

    {/* Section Smart Views */}
    <div className="flex flex-col gap-2 mt-4">
      <h3 className="text-xs font-bold uppercase tracking-wider text-muted-foreground px-3 mb-1">
        Smart Views
      </h3>
      <Button variant="ghost" className="justify-start gap-3 px-3 py-2">
        <StarIcon className="text-amber-500" />
        <span>Favorites</span>
      </Button>
      <Button variant="ghost" className="justify-start gap-3 px-3 py-2">
        <CheckCircleIcon className="text-emerald-500" />
        <span>Tâches</span>
      </Button>
    </div>
  </div>

  {/* Footer avec AI Suggestions */}
  <div className="mt-auto p-4 border-t">
    <div className="rounded-lg border bg-gradient-to-br from-primary/10 to-transparent p-3">
      <div className="flex gap-2 items-start">
        <AutoAwesomeIcon className="text-primary text-sm mt-0.5" />
        <div>
          <p className="text-xs font-semibold">AI Suggestions</p>
          <p className="text-[10px] leading-relaxed text-muted-foreground">
            2 nouvelles suggestions pour "Voyage"
          </p>
        </div>
      </div>
    </div>
  </div>
</aside>

GRILLE MASONRY (3 colonnes)

<main className="flex-1 overflow-y-auto bg-muted p-6 md:p-10">
  <div className="max-w-6xl mx-auto flex flex-col gap-8">
    
    {/* En-tête de page */}
    <div className="flex flex-wrap items-center justify-between gap-4">
      <div className="flex flex-col gap-1">
        <div className="flex items-center gap-2 text-sm text-muted-foreground">
          <span>Notebooks</span>
          <ChevronRightIcon />
          <span className="text-primary">Voyage</span>
        </div>
        <h1 className="text-4xl font-black tracking-tight flex items-center gap-3">
          <span className="bg-primary/10 p-2 rounded-xl text-3xl">
            ✈️
          </span>
          Voyage
        </h1>
      </div>
      
      <div className="flex items-center gap-3">
        <Button variant="outline" size="sm">
          <FilterListIcon />
          Filtrer
        </Button>
        <Button className="shadow-lg">
          <AddIcon />
          Ajouter Note
        </Button>
      </div>
    </div>

    {/* Grille Masonry */}
    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
      {/* Cartes de notes (voir ci-dessous) */}
      {[...notes].map(note => (
        <NoteCard key={note.id} note={note} />
      ))}
    </div>
  </div>
</main>

CARTE NOTE (DESKTOP)

<Card className="group relative flex flex-col rounded-lg overflow-hidden bg-card shadow-sm hover:shadow-xl hover:-translate-y-1 transition-all duration-300 border h-[380px]">
  
  {/* Menu d'action (au survol) */}
  <div className="absolute top-4 right-4 z-10 opacity-0 group-hover:opacity-100 transition-opacity">
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button variant="ghost" className="bg-background/90 rounded-full p-2">
          <MoreHorizIcon />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem>
          <PushPinIcon /> Épingler
        </DropdownMenuItem>
        <DropdownMenuItem>
          <FolderOpenIcon /> Déplacer
        </DropdownMenuItem>
        <DropdownMenuItem>
          <BellIcon /> Rappel
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Link2Icon /> Connexions
        </DropdownMenuItem>
        <DropdownMenuItem>
          <PaletteIcon /> Couleur
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Share2Icon /> Partager
        </DropdownMenuItem>
        <DropdownMenuItem>
          <ArchiveIcon /> Archiver
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem className="text-destructive">
          <Trash2Icon /> Supprimer
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  </div>

  {/* Zone d'image (si présente) - 60% de hauteur */}
  {note.image && (
    <div className="relative h-3/5 w-full bg-cover bg-center">
      <div className="absolute inset-0 bg-gradient-to-t from-black/60 to-transparent" />
      <div className="absolute bottom-4 left-4 right-4">
        <h3 className="text-white text-xl font-bold leading-tight drop-shadow-md">
          {note.title}
        </h3>
      </div>
      <Image 
        src={note.image} 
        alt={note.title}
        className="absolute inset-0 w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
      />
    </div>
  )}

  {/* Zone de contenu */}
  <div className="flex-1 p-5 flex flex-col justify-between">
    <div className="flex flex-col gap-2">
      {/* Icône + texte */}
      <div className="flex items-start gap-2 text-sm text-muted-foreground">
        {note.icon && (
          <Icon icon={note.icon} className="mt-0.5" />
        )}
        <p className="leading-relaxed">
          {note.contentPreview}
        </p>
      </div>
    </div>

    {/* Tags */}
    <div className="flex flex-wrap gap-2 mt-4">
      {note.labels.map(label => (
        <Badge key={label.id} variant="outline" className="gap-1.5">
          <LabelIcon />
          {label.name}
        </Badge>
      ))}
    </div>
  </div>

  {/* Avatar en bas à gauche */}
  <div className="absolute bottom-2 left-2">
    <Avatar className="size-6 ring-2 ring-background">
      <AvatarImage src={note.author.avatar} />
      <AvatarFallback className="text-xs">
        {note.author.initials}
      </AvatarFallback>
    </Avatar>
  </div>

  {/* Date en bas à droite */}
  <div className="absolute bottom-2 right-2 text-xs text-muted-foreground">
    {formatDistanceToNow(note.date)}
  </div>
</Card>

2. PAGE NOTEBOOK - MOBILE

2.1 Vue d'ensemble

Dimensions : 375x812 (iPhone SE) - jusqu'à 768px (tablette)
Layout : Navigation drawer + Contenu scrollable + Bottom Tab Bar

┌─────────────────────┐
│ [☰] Voyage    [🔍] [...]│ ← HEADER (60px)
├─────────────────────┤
│ FILTRES HORIZONTAUX│ ← SCROLLABLE (36px)
│ [✓ALL] #Hôtels #Vols│
├─────────────────────┤
│                     │
│ CONTENU PRINCIPAL  │ ← VERTICAL LIST (pas masonry)
│ (SCROLLABLE)       │
│                     │
│ ┌─────────────────┐ │
│ │ HERO CARD        │ │ ← Grande carte avec image
│ │ [Image]        │ │   (première note)
│ │ #Vols          │ │
│ │ Tokyo Trip Plan  │ │
│ │ Flight JL005... │ │
│ └─────────────────┘ │
│                     │
│ ┌─────────────────┐ │
│ │ HOTEL CARD      │ │
│ │ Kyoto Ryokan... │ │ ← Carte compacte
│ │ #Hôtels        │ │
│ │ Oct 14 - 17    │ │
│ └─────────────────┘ │
│                     │
│ ┌─────────────────┐ │
│ │ RESTAURANT LIST │ │
│ │ 🍜 Sushi Dai    │ │
│ │ ✅ Rokurinsha  │ │
│ │ ☐ Starbucks    │ │
│ │ #Restos        │ │
│ └─────────────────┘ │
│                     │
│ ┌─────────────────┐ │
│ │ IDEA NOTE        │ │
│ │ 💡 Souvenir...  │ │
│ │ Matcha Kit, ... │ │
│ └─────────────────┘ │
│                     │
├─────────────────────┤
│  [🏠] [📁] [🔍] [⚙️]  │ ← BOTTOM TAB BAR (72px)
└─────────────────────┘
      ↑
   [+] FAB (56px)

2.2 Spécifications détaillées

HEADER MOBILE

<header className="flex items-center justify-between px-4 pt-4 pb-2 sticky top-0 z-20">
  {/* Menu bouton (ouvre le drawer) */}
  <Button variant="ghost" size="icon" className="-ml-2">
    <MenuIcon className="h-7 w-7" />
  </Button>

  {/* Titre de page */}
  <h1 className="text-xl font-extrabold tracking-tight">
    Voyage
  </h1>

  {/* Actions droite */}
  <div className="flex items-center gap-1">
    <Button variant="ghost" size="icon">
      <SearchIcon className="h-6 w-6" />
    </Button>
    <Button variant="ghost" size="icon" className="-mr-2">
      <MoreVertIcon className="h-6 w-6" />
    </Button>
  </div>
</header>

FILTRES HORIZONTAUX (SCROLLABLE)

<div className="w-full overflow-x-auto pb-4 pt-1 hide-scrollbar sticky top-[60px] z-10">
  <div className="flex gap-2 px-4">
    {/* Bouton "All" (actif) */}
    <Button className="h-9 shrink-0 gap-2 rounded-full bg-primary px-5 shadow-lg">
      <CheckIcon />
      <span className="text-sm font-bold">All</span>
    </Button>

    {/* Filtres de labels */}
    {labels.map(label => (
      <Button 
        key={label.id}
        variant="outline"
        className="h-9 shrink-0 px-4 rounded-full"
      >
        <span className="text-sm font-medium">#{label.name}</span>
      </Button>
    ))}
  </div>
</div>

CARTES NOTES MOBILE (VERTICAL LIST)

HERO CARD (première note - avec image)

<Card className="relative overflow-hidden bg-card rounded-2xl shadow-sm group cursor-pointer h-[240px]">
  <div className="absolute inset-0 bg-gradient-to-t from-black/80 via-black/20 to-transparent z-10" />
  
  <Image 
    src={note.image}
    alt={note.title}
    className="absolute inset-0 w-full h-full object-cover group-hover:scale-105 transition-transform duration-700"
  />
  
  <div className="absolute bottom-0 left-0 right-0 p-5 z-20 flex flex-col gap-1.5">
    <div className="flex items-center gap-2">
      <Badge className="bg-primary text-primary-foreground px-2 py-0.5 text-[10px] uppercase tracking-wider font-bold">
        #Vols
      </Badge>
      <Badge className="bg-background/20 text-background px-2 py-0.5 text-[10px] uppercase tracking-wider font-bold backdrop-blur-md">
        Next Up
      </Badge>
    </div>
    <h2 className="text-white text-2xl font-bold leading-tight">
      {note.title}
    </h2>
    <p className="text-background/80 text-sm font-medium line-clamp-1">
      {note.contentPreview}
    </p>
  </div>
</Card>

CARTE COMPACTE (sans image)

<Card className="bg-card p-4 rounded-2xl shadow-sm border flex flex-col cursor-pointer hover:border-primary/30 transition-colors">
  <Badge className="self-start mb-2 text-[10px] font-bold">
    #Hôtels
  </Badge>
  
  <h3 className="text-base font-bold leading-tight mb-2">
    {note.title}
  </h3>
  
  <p className="text-xs text-muted-foreground line-clamp-3 mb-3">
    {note.contentPreview}
  </p>
  
  <div className="mt-auto flex items-center gap-1 text-[10px] text-muted-foreground">
    <CalendarIcon />
    <span>{formatDate(note.date)}</span>
  </div>
</Card>

CARTE LISTE (checklist)

<Card className="bg-card p-4 rounded-2xl shadow-sm border flex flex-col cursor-pointer">
  <h3 className="text-sm font-bold mb-2">
    {note.title}
  </h3>
  
  <ul className="space-y-1.5">
    {note.items.map((item, index) => (
      <li key={index} className="flex items-center gap-2">
        <div className="size-4 rounded-full border-2 border-border bg-card flex items-center justify-center shrink-0">
          {item.checked && (
            <CheckIcon className="text-xs" />
          )}
        </div>
        <span className={`text-xs ${item.checked ? 'text-muted-foreground line-through' : ''}`}>
          {item.text}
        </span>
      </li>
    ))}
  </ul>
  
  <div className="mt-3">
    <Badge>#Restos</Badge>
  </div>
</Card>

BOTTOM TAB BAR (72px)

<nav className="fixed bottom-0 w-full bg-background/90 backdrop-blur-lg border-t z-40 pb-safe">
  <div className="flex justify-around items-center h-[72px] pb-2">
    {/* Home */}
    <Button variant="ghost" className="flex-col items-center justify-center w-16 gap-1">
      <HomeIcon className="h-6 w-6" />
      <span className="text-[10px]">Home</span>
    </Button>

    {/* Notebooks (actif) */}
    <Button variant="ghost" className="flex-col items-center justify-center w-16 gap-1 text-primary">
      <FolderIcon className="h-6 w-6 fill" />
      <span className="text-[10px] font-bold">Notebooks</span>
    </Button>

    {/* Espace vide pour le FAB */}
    <div className="w-8" />

    {/* Search */}
    <Button variant="ghost" className="flex-col items-center justify-center w-16 gap-1">
      <SearchIcon className="h-6 w-6" />
      <span className="text-[10px]">Search</span>
    </Button>

    {/* Settings */}
    <Button variant="ghost" className="flex-col items-center justify-center w-16 gap-1">
      <SettingsIcon className="h-6 w-6" />
      <span className="text-[10px]">Settings</span>
    </Button>
  </div>
</nav>

FLOATING ACTION BUTTON (FAB)

<Button 
  className="fixed bottom-[90px] right-5 z-30 size-14 bg-primary text-primary-foreground rounded-2xl shadow-lg shadow-primary/30 hover:scale-105 active:scale-95 transition-all group"
>
  <AddIcon className="h-8 w-8 group-hover:rotate-90 transition-transform duration-300" />
</Button>

3. PAGE ADMIN

3.1 Vue d'ensemble

Layout : Sidebar navigation + Contenu principal avec tableau de bord

┌─────────────────────────────────────────────────────────────────────────────┐
│ HEADER ADMIN (64px)                                               │
│ [LOGO ADMIN] [RECHERCHE] [NOTIFS] [AVATAR ADMIN]                      │
├──────────────┬──────────────────────────────────────────────────────────────┤
│              │                                                      │
│ SIDEBAR      │ CONTENU PRINCIPAL                                    │
│ NAVIGATION  │                                                      │
│ (256px)      │                                                      │
│              │ ┌──────────────────────────────────────────────────┐     │
│ 📊 DASHBOARD│ │ 📊 ADMIN DASHBOARD                          │     │
│              │ │                                          │     │
│ 👥 UTILISATEURS│ │ ┌──────────┐  ┌──────────┐  ┌───────┐│     │
│              │ │ │ Utilisa  │  │ Notes     │  │ AI Met ││     │
│ 📈 ANALYTIQUE│ │ │teurs    │  │          │  │ rics   ││     │
│              │ │ │ Active   │  │ Total    │  │ Tokens ││     │
│ ⚙️ CONFIG     │ │ │ 156     │  │ 1,234   │  │ 45.2K ││     │
│              │ │ │ (+12)  │  │ (+89)   │  │       ││     │
│ 🔒 SÉCURITÉ  │ │ └──────────┘  └──────────┘  └───────┘│     │
│              │ │                                          │     │
│ 💰 COÛTS AI   │ │ ┌────────────────────────────────────────┐ │     │
│              │ │ │ Utilisation AI par jour                │ │     │
│ 📝 JOURNAL     │ │ │ 📊 [Graphique en ligne]              │ │     │
│              │ │ │                                        │ │     │
│ 🔔 NOTIFS     │ │ │ [Graphique circulaire par feature]    │ │     │
│              │ │ └────────────────────────────────────────┘ │     │
│              │ │                                          │     │
│              │ │ ┌────────────────────────────────────────┐ │     │
│              │ │ │ ACTIONS RAPIDES                      │ │     │
│              │ │ └────────────────────────────────────────┘ │     │
│              │ │                                          │     │
│              │ └──────────────────────────────────────────────────┘     │
└──────────────┴──────────────────────────────────────────────────────────────┘

3.2 Spécifications détaillées

HEADER ADMIN

<header className="h-16 flex items-center justify-between px-6 border-b bg-background z-20">
  {/* Logo + titre */}
  <div className="flex items-center gap-3">
    <div className="size-8 bg-amber-500 rounded-lg flex items-center justify-center text-white">
      <AdminPanelSettingsIcon />
    </div>
    <div>
      <h1 className="text-xl font-bold">Admin Console</h1>
      <p className="text-xs text-muted-foreground">Keep Platform Management</p>
    </div>
  </div>

  {/* Recherche */}
  <label className="hidden lg:flex w-96">
    <div className="flex w-full h-10 rounded-xl bg-muted focus-within:ring-2">
      <SearchIcon className="muted-foreground ml-4" />
      <input 
        className="flex-1 bg-transparent px-3 text-sm focus:ring-0"
        placeholder="Rechercher utilisateurs, notes..."
      />
    </div>
  </label>

  {/* Actions droite */}
  <div className="flex items-center gap-3">
    <Badge variant="secondary" className="gap-1">
      <DotIcon className="size-2 fill-green-500" />
      Système en ligne
    </Badge>
    <Button variant="ghost" size="icon">
      <BellIcon />
      <Badge className="absolute -top-1 -right-1 size-4 bg-destructive rounded-full text-[10px] text-white flex items-center justify-center">
        3
      </Badge>
    </Button>
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Avatar className="size-10 ring-2 ring-background cursor-pointer">
          <AvatarImage src={admin.avatar} />
          <AvatarFallback>AD</AvatarFallback>
        </Avatar>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem>
          <UserIcon /> Profil Admin
        </DropdownMenuItem>
        <DropdownMenuItem>
          <SettingsIcon /> Paramètres
        </DropdownMenuItem>
        <DropdownMenuSeparator />
        <DropdownMenuItem className="text-destructive">
          <LogOutIcon /> Déconnexion
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  </div>
</header>

SIDEBAR ADMIN

<aside className="w-64 hidden md:flex flex-col border-r bg-background overflow-y-auto">
  <nav className="p-4 flex flex-col gap-2">
    
    {/* Dashboard */}
    <Button 
      variant="ghost"
      className="justify-start gap-3 px-3 py-2.5 bg-primary/10 text-primary"
    >
      <BarChart3Icon />
      Dashboard
    </Button>

    {/* Utilisateurs */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <UsersIcon />
      Utilisateurs
    </Button>

    {/* Analytics */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <TrendingUpIcon />
      Analytics
    </Button>

    {/* Configuration */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <SettingsIcon />
      Configuration
    </Button>

    {/* Sécurité */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <ShieldIcon />
      Sécurité
    </Button>

    {/* Coûts AI */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <CreditCardIcon />
      Coûts AI
    </Button>

    {/* Journal */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <FileTextIcon />
      Journal d'audit
    </Button>

    {/* Notifications */}
    <Button variant="ghost" className="justify-start gap-3 px-3 py-2.5">
      <BellIcon />
      Notifications
    </Button>

  </nav>

  {/* Footer */}
  <div className="mt-auto p-4 border-t">
    <div className="text-xs text-muted-foreground">
      <p>Keep v{version}</p>
      <p className="mt-1">© 2026 Keep Platform</p>
    </div>
  </div>
</aside>

CARDS MÉTRIQUES

<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
  {/* Carte Utilisateurs */}
  <Card className="p-6">
    <div className="flex items-center justify-between mb-4">
      <div className="flex items-center gap-2">
        <UsersIcon className="text-muted-foreground" />
        <h3 className="font-semibold">Utilisateurs</h3>
      </div>
      <Badge variant="outline">Actifs</Badge>
    </div>
    
    <div className="flex items-end gap-2">
      <p className="text-4xl font-bold">156</p>
      <Badge className="mb-1 bg-green-500/10 text-green-600">
        +12 cette semaine
      </Badge>
    </div>
  </Card>

  {/* Carte Notes */}
  <Card className="p-6">
    <div className="flex items-center justify-between mb-4">
      <div className="flex items-center gap-2">
        <FileTextIcon className="text-muted-foreground" />
        <h3 className="font-semibold">Notes</h3>
      </div>
    </div>
    
    <div className="flex items-end gap-2">
      <p className="text-4xl font-bold">1,234</p>
      <Badge className="mb-1 bg-blue-500/10 text-blue-600">
        +89 aujourd'hui
      </Badge>
    </div>
  </Card>

  {/* Carte AI Metrics */}
  <Card className="p-6">
    <div className="flex items-center justify-between mb-4">
      <div className="flex items-center gap-2">
        <SparklesIcon className="text-muted-foreground" />
        <h3 className="font-semibold">AI Tokens</h3>
      </div>
      <Badge variant="outline">Ce mois</Badge>
    </div>
    
    <div className="flex items-end gap-2">
      <p className="text-4xl font-bold">45.2K</p>
      <Badge className="mb-1 bg-purple-500/10 text-purple-600">
         12% vs mois dernier
      </Badge>
    </div>
  </Card>
</div>

4. PAGE PROFIL

4.1 Vue d'ensemble

Layout : Header avec avatar + Contenu principal organisé en sections

┌─────────────────────────────────────────────────────────────────────────────┐
│ HEADER PROFIL (avec bannière)                                        │
│ [BANNIÈRE IMAGE]                                                   │
│ [AVATAR 96px] [NOM COMPLET] [EMAIL]              [✏️ ÉDITER]    │
│ [BIO]                                              [⚙️ PARAMÈTRES] │
├──────────────────────────────────────────────────────────────────────────────┤
│                                                                      │
│ CONTENU (scrollable)                                                │
│                                                                      │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 📊 STATISTIQUES                                                │ │
│ │ ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐ │ │
│ │ │ 156     │  │ 1,234   │  │ 23      │  │ 4       │ │ │
│ │ │ Notes   │  │ Labels   │  │ Notebooks│  │ Jours   │ │ │
│ │ └──────────┘  └──────────┘  └──────────┘  └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 🎨 THÈMES                                                      │ │
│ │ ┌──────────┐  ┌──────────┐  ┌──────────┐  ┌──────────┐ │ │
│ │ │ ☀️ Light │  │ 🌙 Dark  │  │ 🌊 Midnight│  │ 📖 Sepia │ │ │
│ │ │        │  │   ✅    │  │          │  │          │ │ │
│ │ └──────────┘  └──────────┘  └──────────┘  └──────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ ⚙️ PARAMÈTRES PRÉFÉRÉNCES                                     │ │
│ │ ┌────────────────────────────────────────────────────────────────────┐  │ │
│ │ │ Langue : 🇫🇷 Français                                 │  │ │
│ │ │ Fuseau : 🕐 Central European Time                 │  │ │
│ │ │ Email : ✅ Recevoir les notifications                  │  │ │
│ │ │ Privacy : ✅ Profile public                           │  │ │
│ │ └────────────────────────────────────────────────────────────────────┘  │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 🔐 SÉCURITÉ                                                    │ │
│ │ [Mot de passe] [✏️ Modifier]                                   │ │
│ │ [2FA] [✏️ Configurer]                                        │ │
│ │ [Sessions actives] [👁️ Voir]                                   │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
│                                                                      │
│ ┌──────────────────────────────────────────────────────────────────────────┐ │
│ │ 🤖 AI SETTINGS                                                   │ │
│ │ ┌────────────────────────────────────────────────────────────────────┐  │ │
│ │ │ Provider : [Auto ▼]                                       │  │ │
│ │ │                                                                │  │ │
│ │ │ ☑️ Suggestions de titres                                   │  │ │
│ │ │ ☑️ Recherche sémantique                                    │  │ │
│ │ │ ☑️ Reformulation de paragraphes                               │  │ │
│ │ │ ☑️ Memory Echo (1/jour)                                   │  │ │
│ │ └────────────────────────────────────────────────────────────────────┘  │ │
│ └──────────────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────────────┘

4.2 Spécifications détaillées

HEADER PROFIL (AVEC BANNIÈRE)

<div className="relative">
  {/* Bannière image */}
  <div className="h-48 bg-gradient-to-br from-primary/20 to-primary/5" />
  
  <div className="max-w-4xl mx-auto px-6 -mt-16">
    <Card className="border-2 bg-background shadow-lg">
      <CardContent className="p-6">
        <div className="flex items-start gap-6">
          {/* Avatar */}
          <Avatar className="size-24 ring-4 ring-background shadow-lg">
            <AvatarImage src={user.avatar} />
            <AvatarFallback className="text-2xl font-bold">
              {user.initials}
            </AvatarFallback>
          </Avatar>

          {/* Infos utilisateur */}
          <div className="flex-1">
            <div className="flex items-center justify-between mb-2">
              <div>
                <h1 className="text-2xl font-bold">{user.fullName}</h1>
                <p className="text-sm text-muted-foreground">{user.email}</p>
              </div>
              
              <div className="flex gap-2">
                <Button variant="outline" size="sm">
                  <EditIcon />
                  Éditer profil
                </Button>
                <Button variant="ghost" size="icon">
                  <SettingsIcon />
                </Button>
              </div>
            </div>

            {/* Bio */}
            <p className="text-sm text-muted-foreground">
              {user.bio || "Aucune bio renseignée"}
            </p>
          </div>
        </div>
      </CardContent>
    </Card>
  </div>
</div>

SECTION STATISTIQUES

<section className="max-w-4xl mx-auto px-6 py-8">
  <h2 className="text-lg font-semibold mb-4">📊 Statistiques</h2>
  
  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
    <Card className="p-4 text-center">
      <p className="text-3xl font-bold text-primary">{stats.notesCount}</p>
      <p className="text-xs text-muted-foreground mt-1">Notes</p>
    </Card>
    
    <Card className="p-4 text-center">
      <p className="text-3xl font-bold text-secondary">{stats.labelsCount}</p>
      <p className="text-xs text-muted-foreground mt-1">Labels</p>
    </Card>
    
    <Card className="p-4 text-center">
      <p className="text-3xl font-bold text-accent">{stats.notebooksCount}</p>
      <p className="text-xs text-muted-foreground mt-1">Notebooks</p>
    </Card>
    
    <Card className="p-4 text-center">
      <p className="text-3xl font-bold text-muted-foreground">{stats.daysActive}</p>
      <p className="text-xs text-muted-foreground mt-1">Jours actifs</p>
    </Card>
  </div>
</section>

SECTION THÈMES

<section className="max-w-4xl mx-auto px-6 py-8">
  <h2 className="text-lg font-semibold mb-4">🎨 Thème</h2>
  
  <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
    {themes.map(theme => (
      <Card 
        key={theme.id}
        className={`cursor-pointer transition-all hover:scale-105 ${
          currentTheme === theme.id ? 'ring-2 ring-primary' : ''
        }`}
        onClick={() => setTheme(theme.id)}
      >
        <CardContent className="p-4 text-center">
          <div className="text-3xl mb-2">{theme.icon}</div>
          <p className="text-sm font-medium">{theme.name}</p>
          {currentTheme === theme.id && (
            <CheckIcon className="mx-auto mt-2 text-primary" />
          )}
        </CardContent>
      </Card>
    ))}
  </div>
</section>

5. COMPOSANTS UI RÉUTILISABLES

5.1 Bouton

<Button
  variant="default" // | "outline" | "ghost" | "destructive"
  size="default" // | "sm" | "icon" | "lg"
  className="h-9 px-4 py-2 text-sm font-medium rounded-md transition-colors duration-200"
>
  {/* content */}
</Button>

5.2 Badge

<Badge
  variant="default" // | "outline" | "secondary" | "destructive"
  className="rounded-full px-2 py-0.5 text-xs font-medium"
>
  {/* content */}
</Badge>

5.3 Input

<Input
  type="text" // | "email" | "password" | "search"
  className="h-9 px-3 py-2 text-sm rounded-md border border-input focus-visible:ring-2 focus-visible:ring-ring/50"
  placeholder="Placeholder"
/>

5.4 Card

<Card className="rounded-xl border p-4 shadow-sm hover:shadow-md transition-all duration-200">
  <CardHeader>
    <CardTitle className="text-lg font-medium">Titre</CardTitle>
  </CardHeader>
  <CardContent>
    {/* content */}
  </CardContent>
</Card>

6. DESIGN SYSTEM UNIFIED

6.1 Palette de couleurs

/* Primary */
--primary: #356ac0;
--primary-foreground: #ffffff;

/* Secondary */
--secondary: #f7f7f8;
--secondary-foreground: #1a1d23;

/* Accent */
--accent: #356ac0/10;
--accent-foreground: #356ac0;

/* Muted */
--muted: #f7f7f8;
--muted-foreground: #64748b;

/* Background */
--background: #ffffff;
--foreground: #0f172a;

/* Card */
--card: #ffffff;
--card-foreground: #0f172a;

/* Border */
--border: #e2e8f0;

/* Input */
--input: #e2e8f0;

/* Ring */
--ring: #356ac0;

/* Destructive */
--destructive: #ef4444;
--destructive-foreground: #ffffff;

6.2 Typographie

/* Font Sizes */
--text-xs: 0.75rem;    /* 12px - Labels, badges */
--text-sm: 0.875rem;   /* 14px - Body text */
--text-base: 1rem;     /* 16px - Cards */
--text-lg: 1.125rem;   /* 18px - Headers */
--text-xl: 1.25rem;    /* 20px - Page titles */
--text-2xl: 1.5rem;    /* 24px - Hero */

/* Font Weights */
--font-normal: 400;
--font-medium: 500;
--font-semibold: 600;
--font-bold: 700;

6.3 Spacing (4px base unit)

--spacing-1: 0.25rem;  /* 4px */
--spacing-2: 0.5rem;   /* 8px */
--spacing-3: 0.75rem;  /* 12px */
--spacing-4: 1rem;     /* 16px */
--spacing-6: 1.5rem;   /* 24px */
--spacing-8: 2rem;     /* 32px */

6.4 Border Radius

--radius-sm: 0.25rem;   /* 4px */
--radius-md: 0.375rem;  /* 6px */
--radius-lg: 0.5rem;    /* 8px */
--radius-xl: 0.75rem;   /* 12px */
--radius-2xl: 1rem;     /* 16px */
--radius-full: 9999px;   /* Circular */

6.5 Shadows

--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1);

6.6 Transitions

--transition-colors: color 200ms;
--transition-opacity: opacity 150ms;
--transition-transform: transform 200ms;
--transition-all: all 200ms;

CHECKLIST D'IMPLÉMENTATION

Phase 1 : Foundation

  • Configurer Tailwind avec Design System
  • Créer les composants UI de base (Button, Badge, Input, Card)
  • Mettre à jour globals.css avec les variables CSS
  • Tester tous les thèmes (light, dark, midnight, sepia)

Phase 2 : Desktop Notebook

  • Implémenter Header global
  • Implémenter Sidebar gauche
  • Implémenter Grille Masonry (3 colonnes)
  • Implémenter NoteCard avec menu "..."
  • Tester responsive (lg, xl, 2xl)

Phase 3 : Mobile Notebook

  • Implémenter Header mobile
  • Implémenter Filtres horizontaux scrollables
  • Implémenter Cartes notes (hero, compacte, liste)
  • Implémenter Bottom Tab Bar
  • Implémenter FAB
  • Tester sur mobile (< 768px)

Phase 4 : Admin

  • Implémenter Header admin
  • Implémenter Sidebar admin
  • Implémenter Dashboard avec métriques
  • Tester responsive

Phase 5 : Profil

  • Implémenter Header avec bannière
  • Implémenter Section Statistiques
  • Implémenter Section Thèmes
  • Implémenter Section Paramètres
  • Tester responsive

Phase 6 : Tests Playwright

  • Créer tests pour NoteCard
  • Créer tests pour Sidebar
  • Créer tests pour modales
  • Créer tests pour navigation mobile
  • Définir procédure en cas d'échec

Statut du document : ACTIF
Date de création : 2026-01-17
Version : 1.0
Responsable : John - Product Manager