feat: Complete internationalization and code cleanup

## Translation Files
- Add 11 new language files (es, de, pt, ru, zh, ja, ko, ar, hi, nl, pl)
- Add 100+ missing translation keys across all 15 languages
- New sections: notebook, pagination, ai.batchOrganization, ai.autoLabels
- Update nav section with workspace, quickAccess, myLibrary keys

## Component Updates
- Update 15+ components to use translation keys instead of hardcoded text
- Components: notebook dialogs, sidebar, header, note-input, ghost-tags, etc.
- Replace 80+ hardcoded English/French strings with t() calls
- Ensure consistent UI across all supported languages

## Code Quality
- Remove 77+ console.log statements from codebase
- Clean up API routes, components, hooks, and services
- Keep only essential error handling (no debugging logs)

## UI/UX Improvements
- Update Keep logo to yellow post-it style (from-yellow-400 to-amber-500)
- Change selection colors to #FEF3C6 (notebooks) and #EFB162 (nav items)
- Make "+" button permanently visible in notebooks section
- Fix grammar and syntax errors in multiple components

## Bug Fixes
- Fix JSON syntax errors in it.json, nl.json, pl.json, zh.json
- Fix syntax errors in notebook-suggestion-toast.tsx
- Fix syntax errors in use-auto-tagging.ts
- Fix syntax errors in paragraph-refactor.service.ts
- Fix duplicate "fusion" section in nl.json

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Ou une version plus courte si vous préférez :

feat(i18n): Add 15 languages, remove logs, update UI components

- Create 11 new translation files (es, de, pt, ru, zh, ja, ko, ar, hi, nl, pl)
- Add 100+ translation keys: notebook, pagination, AI features
- Update 15+ components to use translations (80+ strings)
- Remove 77+ console.log statements from codebase
- Fix JSON syntax errors in 4 translation files
- Fix component syntax errors (toast, hooks, services)
- Update logo to yellow post-it style
- Change selection colors (#FEF3C6, #EFB162)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-11 22:26:13 +01:00
parent fc2c40249e
commit 7fb486c9a4
183 changed files with 48288 additions and 1290 deletions

View File

@@ -1,15 +1,16 @@
---
stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
inputDocuments:
- _bmad-output/planning-artifacts/prd-phase1-mvp-ai.md
- docs/component-inventory.md
- docs/project-overview.md
workflowType: 'ux-design'
lastStep: 11
lastStep: 14
documentTitle: 'UX Design Specification - Phase 1 MVP AI'
focusArea: 'AI-Powered Note Taking Features'
status: 'in-progress'
status: 'complete'
createdAt: '2026-01-10'
completedAt: '2026-01-10'
---
# UX Design Specification - Phase 1 MVP AI
@@ -2632,3 +2633,945 @@ Build 7 custom components on top of Radix primitives:
- **MemoryEchoCard:** Defining "Aha!" experience but most complex (background processing, embeddings, feedback learning)
---
## UX Consistency Patterns
### Button Hierarchy
**When to Use:**
- **Primary Buttons:** Main actions (Save note, Apply suggestion, Create Cahier)
- **Secondary Buttons:** Alternative actions (Cancel, Keep original)
- **Tertiary Buttons:** Low-emphasis actions (Dismiss, Skip, Later)
- **AI Buttons:** AI-specific actions (✨ Reformulate, View Connection)
**Visual Design:**
| Button Type | Tailwind Classes | Usage | Example |
|-------------|------------------|-------|---------|
| Primary | `bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-4 rounded-lg` | Main action, high emphasis | "Save Note", "Apply Suggestion" |
| Secondary | `bg-gray-100 hover:bg-gray-200 text-gray-700 font-medium py-2 px-4 rounded-lg` | Alternative action | "Cancel", "Keep Original" |
| Tertiary | `text-gray-500 hover:text-gray-700 font-medium py-2 px-2` | Low emphasis, text-only | "Dismiss", "Skip" |
| AI Action | `bg-purple-50 hover:bg-purple-100 text-purple-600 font-medium py-2 px-4 rounded-lg border border-purple-200` | AI-specific action | "✨ Reformulate", "View Connection" |
| Success | `bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-lg` | Positive confirmation | "Link Notes", "Accept" |
| Destructive | `bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-lg` | Destructive action | "Delete Note", "Remove" |
**Behavior:**
- **Focus:** 2px purple outline (`focus-visible:ring-2 ring-purple-600`)
- **Active:** Slightly darker shade (`active:scale-95`)
- **Disabled:** `opacity-50 cursor-not-allowed` with `aria-disabled="true"`
- **Loading:** Show spinner, disable button, preserve width
**Accessibility:**
- Minimum touch target: 44×44px (WCAG 2.5.5)
- Clear visual labels (no icon-only buttons without labels)
- Keyboard: Enter/Space to activate
- Focus indicators always visible
**Mobile Considerations:**
- Full-width buttons on mobile for primary actions
- Minimum 44px height for touch targets
- Adequate spacing between buttons (8px minimum)
---
### Feedback Patterns
**When to Use:**
- **Success Feedback:** Actions completed successfully (Note saved, Suggestion applied)
- **Error Feedback:** Actions failed (AI unavailable, Connection error)
- **Warning Feedback:** Caution needed (Last Cahier, AI limit reached)
- **Info Feedback:** Neutral information (AI processing, Feature discovery)
**Visual Design:**
**Success Feedback:**
```tsx
// Toast notification
<div className="bg-green-50 border-l-4 border-green-600 text-green-800 p-4 rounded-lg shadow-md">
<div className="flex items-center gap-3">
<span className="text-green-600"></span>
<p className="font-medium">Note saved successfully</p>
</div>
</div>
```
**Error Feedback:**
```tsx
// Toast notification
<div className="bg-red-50 border-l-4 border-red-600 text-red-800 p-4 rounded-lg shadow-md">
<div className="flex items-center gap-3">
<span className="text-red-600"></span>
<p className="font-medium">AI service unavailable. Please try again.</p>
</div>
<button className="mt-2 text-sm underline">Retry</button>
</div>
```
**Warning Feedback:**
```tsx
// Modal or banner
<div className="bg-amber-50 border-l-4 border-amber-600 text-amber-800 p-4 rounded-lg">
<div className="flex items-center gap-3">
<span className="text-amber-600"></span>
<p className="font-medium">You've reached your daily AI limit</p>
</div>
<p className="text-sm mt-1">Upgrade to Pro for unlimited AI features.</p>
</div>
```
**Info Feedback (AI Processing):**
```tsx
// Inline indicator
<div className="flex items-center gap-2 text-gray-600">
<div className="animate-spin w-4 h-4 border-2 border-amber-500 border-t-transparent rounded-full" />
<span className="text-sm">AI thinking...</span>
</div>
```
**Behavior:**
- **Auto-dismiss:** Success/info toasts auto-dismiss after 5s
- **Persistent:** Error/warning toasts require manual dismissal
- **Position:** Toasts bottom-right (desktop), bottom-center (mobile)
- **Stacking:** Multiple toasts stack vertically with 4px gap
**Accessibility:**
- `role="alert"` for errors/warnings
- `role="status"` for success/info
- `aria-live="polite"` for non-critical, `aria-live="assertive"` for critical
- Screen reader announcements with clear messages
---
### Form & Input Patterns
**When to Use:**
- Note editor (main content input)
- Title input (with AI suggestions)
- Cahier name input
- Search bar (unified semantic search)
- Settings forms (AI configuration)
**Visual Design:**
**Text Input (Title, Cahier Name):**
```tsx
<input
type="text"
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent outline-none transition-all"
placeholder="Note title..."
/>
```
**Textarea (Note Content):**
```tsx
<textarea
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent outline-none transition-all min-h-[200px] resize-y"
placeholder="Start typing..."
/>
```
**Search Input (Unified):**
```tsx
<div className="relative">
<input
type="search"
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent outline-none transition-all"
placeholder="Search notes..."
/>
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">🔍</span>
</div>
```
**Behavior:**
- **Focus:** Purple ring (`focus:ring-2 focus:ring-purple-600`)
- **Error state:** Red border + error message below
- **Success state:** Green border (briefly, then normal)
- **AI Suggestions:** Show dropdown below input (TitleSuggestionsDropdown)
- **Debounce:** Search input debounces 300ms before triggering
**Validation Patterns:**
| Field | Validation | Error Message |
|-------|-----------|---------------|
| Cahier Name | Required, min 2 chars | "Cahier name must be at least 2 characters" |
| Title | Optional (AI suggests if empty) | - |
| Search | Min 2 chars to trigger | "Enter at least 2 characters to search" |
**Accessibility:**
- `aria-label` or `aria-labelledby` for all inputs
- `aria-describedby` for help text/error messages
- `aria-invalid="true"` for validation errors
- Keyboard navigation: Tab to focus, Enter to submit
---
### Navigation Patterns
**When to Use:**
- Cahier switching (sidebar navigation)
- Breadcrumb navigation (header)
- Tab navigation (settings sections)
- Pagination (masonry grid infinite scroll)
**Visual Design:**
**Cahier Sidebar Navigation:**
```tsx
<nav className="w-64 bg-white border-r border-gray-200">
<ul className="py-4">
<li>
<button className="w-full flex items-center gap-3 px-4 py-2 text-left bg-purple-50 text-purple-600 border-l-4 border-purple-600 font-medium">
📓 Inbox
</button>
</li>
<li>
<button className="w-full flex items-center gap-3 px-4 py-2 text-left text-gray-700 hover:bg-gray-50">
📓 Work
</button>
</li>
<li>
<button className="w-full flex items-center gap-3 px-4 py-2 text-left text-gray-700 hover:bg-gray-50">
📓 Personal
</button>
</li>
</ul>
</nav>
```
**Active State:**
- Background: `bg-purple-50`
- Text: `text-purple-600`
- Left border: `border-l-4 border-purple-600`
- Font weight: `font-medium`
**Hover State (Inactive):**
- Background: `hover:bg-gray-50`
- Text: `text-gray-700`
- No border
**Breadcrumb Navigation (Header):**
```tsx
<nav className="flex items-center gap-2 text-sm text-gray-600">
<span className="hover:text-purple-600 cursor-pointer">Memento</span>
<span>/</span>
<span className="hover:text-purple-600 cursor-pointer">Work</span>
<span>/</span>
<span className="text-gray-900 font-medium">React Performance Tips</span>
</nav>
```
**Behavior:**
- **Instant switch:** Cahier switching happens < 100ms (no page reload)
- **Active indicator:** Current Cahier highlighted with purple left border
- **Keyboard navigation:** ↑↓ to navigate Cahiers, Enter to select
- **Mobile:** Hamburger menu (sidebar collapses to off-canvas)
**Accessibility:**
- `role="navigation"` with `aria-label="Cahiers navigation"`
- `aria-current="page"` for active Cahier
- Keyboard focus visible (2px purple outline)
- Screen reader announces Cahier names
---
### Modal & Overlay Patterns
**When to Use:**
- Reformulation modal (compare original vs AI suggestion)
- Memory Echo details modal (view 2-note connection)
- Settings modals (AI configuration)
- Confirmation dialogs (delete Cahier)
**Visual Design:**
**Modal Container:**
```tsx
<div className="fixed inset-0 z-50 flex items-center justify-center">
{/* Backdrop */}
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" />
{/* Modal */}
<div className="relative bg-white rounded-xl shadow-2xl max-w-4xl w-full mx-4 border-2 border-purple-600">
{/* Header */}
<div className="flex items-center justify-between p-6 border-b border-gray-200">
<h2 className="text-2xl font-semibold text-gray-900"> Reformulate this Paragraph</h2>
<button className="text-gray-400 hover:text-gray-600"></button>
</div>
{/* Body */}
<div className="p-6">
{/* Modal content */}
</div>
{/* Footer */}
<div className="flex justify-end gap-3 p-6 border-t border-gray-200">
<button>Keep Original</button>
<button>Apply Suggestion</button>
</div>
</div>
</div>
```
**Behavior:**
- **Opening:** Fade-in backdrop + scale modal (0.2s ease-out)
- **Closing:** Fade-out backdrop + scale down (0.1s)
- **Focus trap:** Tab stays within modal when open
- **ESC to close:** Pressing ESC closes modal
- **Click outside:** Clicking backdrop closes modal (optional for confirmation dialogs)
**Accessibility:**
- `role="dialog"` with `aria-modal="true"`
- `aria-labelledby` points to modal title
- Focus trap (first focusable element receives focus on open)
- Returns focus to trigger element on close
**Mobile Considerations:**
- Full-width modals on mobile (mx-0, max-h-screen)
- Bottom sheet style for some modals (slide-up from bottom)
- Touch-friendly button sizes (min 44px)
---
### Search Patterns
**When to Use:**
- Unified semantic search (header search bar)
- Cahier-specific search (filtered by current Cahier)
- AI-powered semantic matching
**Visual Design:**
**Unified Search Bar:**
```tsx
<div className="relative">
<input
type="search"
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-purple-600 focus:border-transparent outline-none transition-all"
placeholder="Search notes..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400">🔍</span>
{/* Loading indicator */}
{isSearching && (
<div className="absolute right-3 top-1/2 -translate-y-1/2">
<div className="animate-spin w-4 h-4 border-2 border-purple-600 border-t-transparent rounded-full" />
</div>
)}
</div>
```
**Search Results with Semantic Badges:**
```tsx
<div className="space-y-4">
{/* Keyword match result */}
<div className="p-4 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-shadow">
<h3 className="font-semibold text-gray-900">React State Management</h3>
</div>
{/* Semantic match result */}
<div className="p-4 bg-white border border-gray-200 rounded-lg hover:shadow-md transition-shadow">
<h3 className="font-semibold text-gray-900">Next.js Optimization</h3>
<div className="mt-2">
<span className="inline-flex items-center gap-1 px-2 py-1 bg-blue-50 text-blue-600 text-xs font-medium rounded">
🎯 Semantic Match (Score: 0.82)
</span>
</div>
</div>
</div>
```
**Behavior:**
- **Debounce:** 300ms debounce before triggering search
- **Hybrid search:** Simultaneously runs keyword + semantic search
- **Badge indication:** Semantic matches show blue badge with score
- **Real-time:** Results update as user types (after debounce)
- **No visible toggle:** Users don't choose keyword vs semantic - "it just works"
**Accessibility:**
- `aria-label="Search notes"`
- Live region for results: `aria-live="polite"` on results container
- Clear announcements: "5 results found, 3 semantic matches"
- Keyboard: Enter to navigate to first result
---
### Loading & Empty States
**When to Use:**
- AI processing (generating embeddings, reformulating)
- Empty Cahiers (no notes yet)
- No search results
- Loading initial data
**Visual Design:**
**AI Processing State:**
```tsx
<div className="flex flex-col items-center justify-center py-12">
<div className="animate-spin w-12 h-12 border-4 border-amber-500 border-t-transparent rounded-full mb-4" />
<p className="text-gray-600 font-medium">AI thinking...</p>
<p className="text-sm text-gray-500 mt-1">Generating embeddings for semantic search</p>
</div>
```
**Empty Cahier State:**
```tsx
<div className="flex flex-col items-center justify-center py-16 text-center">
<div className="text-6xl mb-4">📓</div>
<h3 className="text-xl font-semibold text-gray-900 mb-2">No notes in this Cahier yet</h3>
<p className="text-gray-600 mb-6">Capture your first idea to get started</p>
<button className="bg-purple-600 hover:bg-purple-700 text-white font-medium py-2 px-6 rounded-lg">
Create Note
</button>
</div>
```
**No Search Results:**
```tsx
<div className="flex flex-col items-center justify-center py-12 text-center">
<div className="text-4xl mb-4">🔍</div>
<h3 className="text-lg font-semibold text-gray-900 mb-2">No results found</h3>
<p className="text-gray-600">Try different keywords or check your spelling</p>
</div>
```
**Skeleton Loading (Masonry Grid):**
```tsx
<div className="grid grid-cols-3 gap-4">
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={i} className="h-48 bg-gray-200 rounded-lg animate-pulse" />
))}
</div>
```
**Behavior:**
- **AI Processing:** Show spinner + descriptive text (not just "Loading...")
- **Empty States:** Provide clear CTA (Create Note, Browse Other Cahiers)
- **Skeleton:** Pulse animation while loading actual content
- **Progressive enhancement:** Show content as it loads (not all-or-nothing)
**Accessibility:**
- `role="status"` with `aria-live="polite"` for loading states
- `aria-busy="true"` when content is loading
- Screen readers announce what's happening and why
- Empty states have clear headings and explanations
---
### Mobile-Specific Patterns
**When to Use:**
- Responsive navigation (collapsible sidebar)
- Touch interactions (swipe, long-press)
- Mobile-optimized modals (bottom sheets)
- Mobile search (expandable search bar)
**Visual Design:**
**Collapsible Sidebar (Mobile):**
```tsx
{/* Desktop: Always visible sidebar */}
{/* Mobile: Hamburger menu */}
<div className="md:hidden fixed top-4 left-4 z-50">
<button className="p-2 bg-white rounded-lg shadow-md">
</button>
</div>
{/* Off-canvas sidebar on mobile */}
<div className={`fixed inset-y-0 left-0 z-50 w-64 bg-white transform transition-transform ${isOpen ? 'translate-x-0' : '-translate-x-full'} md:translate-x-0`}>
{/* Sidebar content */}
</div>
```
**Bottom Sheet Modal (Mobile):**
```tsx
<div className="md:hidden fixed inset-x-0 bottom-0 bg-white rounded-t-2xl shadow-2xl transform transition-transform">
<div className="p-6">
{/* Modal content */}
</div>
</div>
```
**Expandable Search (Mobile):**
```tsx
<div className="relative">
<button className="p-2">
🔍
</button>
{/* Expands to full-width input on focus/click */}
<input
type="search"
className="fixed inset-x-4 top-16 z-40 px-4 py-3 bg-white border border-gray-300 rounded-lg shadow-lg"
placeholder="Search notes..."
/>
</div>
```
**Touch Interactions:**
- **Minimum touch target:** 44×44px (WCAG 2.5.5)
- **Swipe to dismiss:** Toast notifications, bottom sheets
- **Long-press:** Context menus (show actions on note card)
- **Pull-to-refresh:** Refresh masonry grid content
---
### Pattern Integration with Radix UI
**Consistency with Design System:**
| Pattern Category | Radix Primitive | Custom Styling | Notes |
|------------------|-----------------|----------------|-------|
| Modals | Dialog | Purple border, AI-specific padding | BaseModal extends Dialog |
| Dropdowns | Dropdown Menu | Purple text on hover | Used for TitleSuggestions |
| Toasts | Toast | Purple border for AI | AIToast extends Toast |
| Navigation | Navigation Menu | Active state = purple left border | Cahiers sidebar |
| Forms | - | Custom inputs with purple focus ring | No Radix form primitive |
**Design Token Integration:**
```css
/* All patterns use consistent design tokens */
--primary: #8B5CF6; /* Primary actions, focus rings */
--ai-accent: #3B82F6; /* Semantic search badges */
--ai-connection: #8B5CF6; /* Memory Echo borders */
--success: #10B981; /* Success feedback */
--warning: #F59E0B; /* Processing states */
--error: #EF4444; /* Error feedback */
```
**Custom Pattern Rules:**
1. **AI-specific patterns always use purple/blue accent colors**
2. **All buttons have 2px purple focus ring** (keyboard navigation)
3. **All modals have purple border** (2px solid #8B5CF6)
4. **All toasts auto-dismiss after 5s** except errors (manual dismiss)
5. **All inputs use purple focus ring** (not default blue)
6. **All empty states provide clear CTA** (not just "No results")
7. **All loading states show descriptive text** (not just spinners)
---
## Responsive Design & Accessibility
### Responsive Strategy
**Desktop Strategy (1024px+):**
- **Layout optimisé:** Sidebar Cahiers (256px) + Masonry grid (3-4 colonnes)
- **Espace maximal:** Profiter de l'écran pour afficher plus de notes
- **Features desktop:**
- Cahier sidebar toujours visible (pas de hamburger)
- Masonry grid 4 colonnes (plus de notes visibles)
- Memory Echo toast en bas à droite
- Hover interactions (✨ Reformulate apparaît au survol)
- Drag & drop pour réorganiser les Cahiers (bonus, pas MVP)
**Tablet Strategy (768px - 1023px):**
- **Layout adapté:** Sidebar Cahiers réduit (200px) ou collapsible
- **Masonry 2 colonnes:** Grid passe de 4 → 2 colonnes
- **Touch optimization:**
- Cahier sidebar devient collapsible (hamburger menu)
- Boutons plus larges (min 44px)
- Pas de hover-based interactions (✨ Reformulate bouton permanent)
- **Information density:** Moyenne - équilibre entre lisibilité et contenu
**Mobile Strategy (< 768px):**
- **Layout simplifié:** Single-column stack
- **Navigation:** Hamburger menu (sidebar off-canvas)
- **Masonry 1 colonne:** Single column, full-width cards
- **Features mobiles:**
- Cahier sidebar: Off-canvas (glisse de gauche)
- Search: Expandable (icône → input full-width)
- Memory Echo: Full-width toast en bas
- AI Badge: Compact (✨ icône seule, tap pour menu)
- Bottom sheet modals (au lieu de dialogues centrés)
- **Critical info only:** Masquer les éléments non-essentiels
---
### Breakpoint Strategy
**Using Tailwind CSS Standard Breakpoints:**
```javascript
// tailwind.config.js
module.exports = {
theme: {
screens: {
'sm': '640px', // Mobile large (landscape)
'md': '768px', // Tablet portrait
'lg': '1024px', // Desktop, laptop
'xl': '1280px', // Desktop large
'2xl': '1536px', // Extra large desktop
}
}
}
```
**Layout Adaptations by Breakpoint:**
| Element | Mobile (< 768px) | Tablet (768-1024px) | Desktop (> 1024px) |
|---------|------------------|---------------------|---------------------|
| Cahier Sidebar | Off-canvas (hamburger) | 200px or collapsible | 256px always visible |
| Masonry Grid | 1 colonne (100%) | 2 colonnes (48% each) | 3-4 colonnes (32-24% each) |
| Header | Compact (64px) | Standard (64px) | Standard (64px) |
| Search Bar | Expandable on tap | Full-width (standard) | Full-width (standard) |
| Memory Echo | Bottom-center toast | Bottom-right toast | Bottom-right toast |
| Modals | Bottom sheet | Standard dialog | Standard dialog |
**Mobile-First Approach:**
- **Développement:** Commencer par le layout mobile, ajouter des médias queries pour écrans plus larges
- **Avantages:** Performance native mobile, progressive enhancement
- **Implementation:**
```css
/* Mobile default: 1 colonne */
.masonry-grid { display: grid; grid-template-columns: 1fr; }
/* Tablet: 2 colonnes */
@media (min-width: 768px) {
.masonry-grid { grid-template-columns: repeat(2, 1fr); }
}
/* Desktop: 3-4 colonnes */
@media (min-width: 1024px) {
.masonry-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1280px) {
.masonry-grid { grid-template-columns: repeat(4, 1fr); }
}
```
---
### Accessibility Strategy
**WCAG Compliance Level: AA (Recommended)**
**Rationale:**
- ✅ **Industry standard:** Niveau attendu pour les applications web modernes
- ✅ **Legal compliance:** Conforme aux exigences légales (ADA, European Accessibility Act)
- ✅ **User experience:** Balance optimal entre accessibilité et design
- ✅ **Feasible:** Atteignable sans compromis majeurs sur le design
**Key Accessibility Requirements:**
**1. Color Contrast (WCAG 2.1 Level AA):**
- Normal text (16px+): Minimum 4.5:1 contrast ratio
- Large text (18px+): Minimum 3:1 contrast ratio
- UI components (buttons, borders): Minimum 3:1 contrast ratio
**Implementation:**
- Purple primary (#8B5CF6) on white: 4.8:1 ✅
- Blue accent (#3B82F6) on white: 4.5:1 ✅
- Green success (#10B981) on white: 3.9:1 ✅ (OK for large text)
- Gray text (#6B7280) on white: 4.6:1 ✅
**2. Keyboard Navigation:**
- **Full keyboard support:** Tab, Shift+Tab, Enter, Escape, Arrow keys
- **Focus indicators:** 2px purple outline (focus-visible:ring-2 ring-purple-600)
- **Skip links:** "Skip to main content" link au début de la page
- **Focus order:** Logique et prévisible (header → sidebar → main content → footer)
- **No keyboard traps:** ESC ferme tous les modals/toasts
**3. Screen Reader Support:**
- **Semantic HTML:** heading hierarchy (h1 → h2 → h3), proper list structures
- **ARIA labels:** Labels descriptifs pour tous les composants interactifs
- **Live regions:** `aria-live="polite"` pour toasts et mises à jour dynamiques
- **Screen reader testing:** NVDA (Windows), VoiceOver (macOS), TalkBack (Android)
**4. Touch Target Sizes (WCAG 2.5.5):**
- Minimum 44×44px pour tous les éléments interactifs
- Espacement minimum 8px entre les éléments tactiles
- Tests sur appareils mobiles réels (iOS, Android)
**5. Focus Management:**
- **Focus trap:** Dans les modals (Tab ne quitte pas le modal)
- **Focus restoration:** Retour au trigger element après fermeture modal
- **Visible focus:** Toujours visible (pas de outline: none sauf :focus-visible)
**6. Accessibility Features for AI Components:**
- **AIToast:** `role="alert"` + `aria-live="polite"`
- **TitleSuggestions:** `role="listbox"` + `aria-label="AI-generated title suggestions"`
- **MemoryEchoCard:** `aria-label="AI notification: Note connection discovered"`
- **ProcessingIndicator:** `role="status"` + `aria-busy="true"`
---
### Testing Strategy
**Responsive Testing:**
**Device Testing:**
- **Real devices:**
- iPhone 12/13/14 (375px width)
- Samsung Galaxy S21 (360px width)
- iPad (768px - 1024px)
- Desktop (1920px width)
- **Browser testing:**
- Chrome (primary)
- Safari (iOS, macOS)
- Firefox (secondary)
- Edge (Windows)
**Network Performance Testing:**
- Test sur 3G (slow network)
- Test sur WiFi (normal network)
- Optimiser images (WebP, lazy loading)
- Minifier CSS/JS pour performance mobile
**Accessibility Testing:**
**Automated Tools:**
- **axe DevTools** (Chrome extension) - Scan automatique
- **WAVE** (WebAIM) - Contrast checker, ARIA validation
- **Lighthouse** (Chrome) - Accessibility score
**Manual Testing:**
- **Keyboard navigation:** Navigation clavier complète
- **Screen reader:** NVDA, VoiceOver, TalkBack
- **Zoom:** Test 200% text zoom (pas de horizontal scroll)
- **High contrast mode:** Windows High Contrast Mode
**User Testing:**
- **Include users with disabilities:**
- Screen reader users
- Low vision users
- Motor disability users (keyboard-only)
- **Test with real assistive technologies**
- **Gather feedback on AI features accessibility**
---
### Implementation Guidelines
**Responsive Development:**
**1. Use Relative Units:**
```css
/* ✅ GOOD - Relative units */
font-size: 1rem; /* 16px base */
padding: 1rem; /* 16px */
margin: 0.5rem 0; /* 8px top/bottom, 0 sides */
width: 100%; /* Full width */
max-width: 1200px; /* Max constraint */
/* ❌ BAD - Fixed pixels */
font-size: 16px; /* Not scalable */
padding: 16px;
width: 375px; /* Mobile fixed width */
```
**2. Mobile-First Media Queries:**
```css
/* Mobile default */
.masonry-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
/* Tablet+ */
@media (min-width: 768px) {
.masonry-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* Desktop+ */
@media (min-width: 1024px) {
.masonry-grid {
grid-template-columns: repeat(3, 1fr);
}
}
```
**3. Touch Target Testing:**
```tsx
// ✅ GOOD - Minimum 44x44px
<button className="min-h-[44px] min-w-[44px] p-4">
Click me
</button>
// ❌ BAD - Too small
<button className="h-8 w-8 p-1">
Click me
</button>
```
**4. Image Optimization:**
```tsx
// Responsive images
<Image
src="/note-thumbnail.webp"
width={400}
height={300}
loading="lazy" // Lazy load below fold
alt="Note thumbnail"
/>
// Background images with fallback
<div
style={{
backgroundImage: 'url(/image.webp), url(/image.jpg)'
}}
/>
```
**Accessibility Development:**
**1. Semantic HTML:**
```tsx
// ✅ GOOD - Semantic
<header>
<nav aria-label="Cahiers navigation">
<ul>
<li><a href="/inbox" aria-current="page">Inbox</a></li>
</ul>
</nav>
</header>
<main>
<article>
<h1>Note Title</h1>
<p>Note content...</p>
</article>
</main>
// ❌ BAD - Non-semantic
<div class="header">
<div class="nav">
<div class="nav-item" onclick="navigate('/inbox')">Inbox</div>
</div>
</div>
```
**2. ARIA Labels and Roles:**
```tsx
// AIToast component
<div
role="alert"
aria-live="polite"
aria-label="AI notification: Note connection discovered"
>
<div className="flex items-center gap-3">
<span aria-hidden="true">💡</span>
<h3>I noticed something...</h3>
</div>
</div>
// TitleSuggestionsDropdown
<ul role="listbox" aria-label="AI-generated title suggestions">
<li role="option">✨ Title 1</li>
<li role="option">✨ Title 2</li>
<li role="option">✨ Title 3</li>
</ul>
```
**3. Keyboard Navigation:**
```tsx
// Focus trap in modal
const Modal = () => {
useEffect(() => {
// Trap focus within modal
const focusableElements = modalRef.current.querySelectorAll(
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);
const firstElement = focusableElements[0];
const lastElement = focusableElements[focusableElements.length - 1];
const handleTab = (e) => {
if (e.key === 'Tab') {
if (e.shiftKey) {
if (document.activeElement === firstElement) {
e.preventDefault();
lastElement.focus();
}
} else {
if (document.activeElement === lastElement) {
e.preventDefault();
firstElement.focus();
}
}
}
};
document.addEventListener('keydown', handleTab);
return () => document.removeEventListener('keydown', handleTab);
}, []);
// Modal JSX...
};
```
**4. Focus Management:**
```tsx
// Skip link (top of page)
<a
href="#main-content"
className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 bg-purple-600 text-white px-4 py-2 rounded-lg"
>
Skip to main content
</a>
<main id="main-content" tabIndex={-1}>
{/* Main content */}
</main>
```
**5. High Contrast Mode Support:**
```css
/* Respect high contrast mode preference */
@media (prefers-contrast: high) {
.ai-button {
border: 2px solid currentColor;
background: transparent;
}
.note-card {
border: 2px solid currentColor;
}
}
```
---
### Component Library Resources
**Alternative UI Component Libraries (Built on Radix UI + Tailwind):**
These libraries are compatible with Memento's design system choice (Radix UI + Tailwind CSS):
1. **Aceternity UI** - https://ui.aceternity.com/components
- Modern components built with Radix UI + Tailwind
- Animated components, dark mode support
- Useful for: Advanced animations, bento grids, particles
2. **Origin UI** - https://www.originui-ng.com/
- Next.js components with Framer Motion animations
- shadcn/ui-based with enhanced styling
- Useful for: Animated cards, transitions, hero sections
3. **Magic UI** - https://magicui.design/docs/components
- Creative components with unique animations
- Built with Radix UI + Tailwind + Framer Motion
- Useful for: Special effects, interactive components
**Recommendation:**
- **Base:** Stick with Radix UI primitives (current choice)
- **Enhancement:** These libraries can provide inspiration or pre-built components for specific features
- **Customization:** All components can be customized to match Memento's design tokens (purple/blue AI colors)
**Integration Strategy:**
1. Start with Radix UI primitives (as planned)
2. Reference these libraries for component patterns and animation ideas
3. Customize any imported components to use Memento's design tokens
4. Maintain consistency with established UX patterns from Step 12
---