## 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>
3578 lines
132 KiB
Markdown
3578 lines
132 KiB
Markdown
---
|
||
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: 14
|
||
documentTitle: 'UX Design Specification - Phase 1 MVP AI'
|
||
focusArea: 'AI-Powered Note Taking Features'
|
||
status: 'complete'
|
||
createdAt: '2026-01-10'
|
||
completedAt: '2026-01-10'
|
||
---
|
||
|
||
# UX Design Specification - Phase 1 MVP AI
|
||
|
||
**Project:** Memento
|
||
**Author:** Ramez
|
||
**Date:** 2026-01-10
|
||
**Focus:** UX Design for AI-Powered Note Taking Features
|
||
|
||
---
|
||
|
||
## Executive Summary
|
||
|
||
### Project Vision
|
||
|
||
**Memento Phase 1 MVP AI** transforms the existing note-taking application into a **proactive cognitive partner** with the philosophy **"Zéro Prise de Tête"** (Zero-Friction Intelligence).
|
||
|
||
**Core Philosophy:** "Suggest and facilitate, never impose"
|
||
|
||
**What Makes It Special:**
|
||
- **Contextual Smart Assistance**: AI features appear only when relevant, not overwhelming
|
||
- **Hybrid Semantic Discovery**: Unified search that "just works" - users don't distinguish keyword vs semantic
|
||
- **Memory Echo** ⭐: Proactive connections between notes that users hadn't seen (the "Aha!" moment)
|
||
- **Privacy-First Multi-Provider**: Ollama (100% local) OR OpenAI (cloud) - user choice
|
||
|
||
**The "Aha!" Moment:**
|
||
> *"I didn't search, it found me"*
|
||
>
|
||
> 💡 *"I noticed something..."*
|
||
> *"You noted `[Node.js performance tips]` in January and `[Next.js optimization]` this week. These notes are connected - want me to link them?"*
|
||
|
||
### Target Users
|
||
|
||
**Primary Personas (from PRD User Journeys):**
|
||
|
||
**1. Alex - Creative Developer (Success Path)**
|
||
- **Profile:** Freelance Creative & Developer, 32, Paris
|
||
- **Problem:** 300+ notes, can't find anything, spends 20min searching
|
||
- **Goals:** Instant capture, intelligent organization
|
||
- **Discovery:** Toast title suggestions → Memory Echo reveals invisible connections → "Hooked!"
|
||
|
||
**2. Max - Privacy Advocate**
|
||
- **Profile:** Privacy Advocate & Software Engineer, 28, Berlin
|
||
- **Problem:** Wants AI but refuses to let data leave his laptop
|
||
- **Goals:** Total control + verifiable (checks DevTools for 0 external calls)
|
||
- **Discovery:** Verifies Ollama = 0 external API calls → Builds trust
|
||
|
||
**3. Léa - System Admin** (Phase 2, not MVP)
|
||
- **Profile:** DevOps Engineer, 35, Lyon - Team admin
|
||
- **Problem:** Configure AI for 15 devs, monitor costs
|
||
- **Goals:** Admin dashboard + AI analytics
|
||
|
||
**4. Sophie - Skeptic to Trust**
|
||
- **Profile:** Content Marketing Manager, 29, Bordeaux
|
||
- **Problem:** AI makes mistakes, learns to trust through customization
|
||
- **Goals:** Personalizable AI settings, feedback learning
|
||
|
||
**User Characteristics:**
|
||
- **Tech-savvy**: Developers, knowledge workers, creatives
|
||
- **Devices**: Desktop (laptop) + Mobile (smartphone/tablet)
|
||
- **Context**: Async work, quick capture in subway, meetings
|
||
|
||
### Key Design Challenges
|
||
|
||
**1. Contextual Smart Assistance Pattern**
|
||
- **Challenge:** Make AI features appear only when relevant
|
||
- **Example:** Title suggestions AFTER 50+ words without title
|
||
- **Question:** How to avoid overwhelming users with too many AI features?
|
||
|
||
**2. Memory Echo - "I Didn't Search, It Found Me"**
|
||
- **Challenge:** Surface proactive connections without appearing spammy
|
||
- **Constraint:** Max 1 insight/day (configurable 0-3)
|
||
- **Question:** How to make every insight feel valuable?
|
||
|
||
**3. Privacy-First Multi-Provider**
|
||
- **Challenge:** Communicate that Ollama = 100% local processing
|
||
- **Solution:** Connection status indicators, verifiable in DevTools
|
||
- **Question:** How to clearly communicate local vs cloud difference?
|
||
|
||
**4. Feedback & Learning**
|
||
- **Challenge:** AI makes mistakes, how to recover user trust?
|
||
- **Solution:** 👍👎 buttons, "Why is this wrong?" modal, customizable settings
|
||
- **Question:** How to make feedback learning visible and reassuring?
|
||
|
||
### Design Opportunities
|
||
|
||
**1. Toast Notification Pattern - Natural Discovery**
|
||
- Instead of hiding features in menus, discover them when relevant
|
||
- Example: "I have 3 title ideas for your note, view them?"
|
||
- **Benefit:** Users discover features without tutorial
|
||
|
||
**2. "Exact Match | Semantic Match" Badges**
|
||
- Hybrid search that "just works" - users don't know how it works
|
||
- Visual badges to distinguish keyword vs semantic results
|
||
- **Benefit:** Educates users without confusing them
|
||
|
||
**3. Memory Echo Card - The "Aha!" Moment**
|
||
- Proactive notification: "I noticed something..."
|
||
- Display 2 connected notes side-by-side
|
||
- 👍👎 buttons for learning
|
||
- **Benefit:** Creates unique emotional moment ("Wow, that's clever!")
|
||
|
||
**4. Granular AI Settings - Total Control**
|
||
- ON/OFF checkboxes for each AI feature
|
||
- Memory Echo frequency slider (0-3/day)
|
||
- **Benefit:** User feels in control, not "spied on by AI"
|
||
|
||
---
|
||
|
||
## Core User Experience
|
||
|
||
### Defining Experience
|
||
|
||
**Core Experience:** "Fast Capture + Intelligent Discovery"
|
||
|
||
Memento Phase 1 MVP AI combines two fundamental experiences:
|
||
|
||
1. **Fast Capture** (Primary - Existing Enhanced)
|
||
- Instant note creation with zero friction
|
||
- Content first, title comes later (or AI-suggested)
|
||
- Markdown supported but not required
|
||
- Capture anywhere: desktop (laptop), mobile (subway, meetings), tablet
|
||
|
||
2. **Intelligent Discovery** (New - Phase 1)
|
||
- AI organizes silently in background
|
||
- Title suggestions appear contextually (after 50+ words without title)
|
||
- Semantic search that "just works"
|
||
- Memory Echo reveals invisible connections between notes
|
||
|
||
**Core User Loop:**
|
||
```
|
||
Capture → AI Organizes → Discover → Capture → ...
|
||
↑_____________↓
|
||
Seamless Flow
|
||
```
|
||
|
||
The critical insight: Capture must remain instant (no AI friction), while AI enhances organization in the background.
|
||
|
||
### Platform Strategy
|
||
|
||
**Primary Platform:** Web Application (Responsive)
|
||
|
||
No native mobile apps - modern browsers provide sufficient capabilities.
|
||
|
||
**Device Breakdown:**
|
||
|
||
| Platform | Viewport | Usage | Interaction Style |
|
||
|----------|----------|-------|-------------------|
|
||
| **Desktop** | 1024px+ | Primary - serious work, content creation | Mouse + Keyboard (shortcuts, power users) |
|
||
| **Tablet** | 640px-1023px | Intermediate - comfortable reading | Touch + Keyboard (hybrid) |
|
||
| **Mobile** | 320px-639px | Quick capture on-the-go | Touch-first (44x44px tap targets) |
|
||
|
||
**Technical Stack:**
|
||
- Next.js 16.1.1 (SSR + App Router)
|
||
- React 19.2.3 (Server + Client Components)
|
||
- Tailwind CSS 4 (utility-first styling)
|
||
- Radix UI (accessible primitives)
|
||
|
||
**Responsive Design Strategy:**
|
||
- Mobile-first approach
|
||
- Progressive enhancement
|
||
- Touch-optimized on mobile, keyboard-optimized on desktop
|
||
|
||
**Offline Requirements:** None for MVP (Phase 2: PWA with offline mode)
|
||
|
||
### Effortless Interactions
|
||
|
||
**1. Zero-Friction Capture**
|
||
- Opening Memento → Type immediately (no login friction after first session)
|
||
- No "choose a title first" → Content comes first
|
||
- Optional markdown formatting (not required)
|
||
- Auto-save as you type
|
||
|
||
**2. Natural Feature Discovery**
|
||
- Toast notification: "I have 3 title ideas for your note, view them?"
|
||
- Options: "View | Not now | Don't ask for this note"
|
||
- User discovers AI features when relevant, not via tutorial
|
||
- Non-intrusive, respectful of user's flow
|
||
|
||
**3. Memory Echo "Aha!" Moment**
|
||
- Subtle notification: "I noticed something..."
|
||
- Max 1 insight/day (configurable 0-3)
|
||
- When relevant → User thinks: "That's clever!"
|
||
- Not spammy, each insight feels valuable
|
||
|
||
**4. Search That "Just Works"**
|
||
- User types naturally: "how to optimize React performance"
|
||
- Results show with badges: "Exact Match | Semantic Match"
|
||
- User doesn't know how it works, but it finds the note
|
||
- Hybrid search = keywords + semantic mixed, no user configuration needed
|
||
|
||
**5. Privacy-First Transparency**
|
||
- Clear indicators: "✅ Connected to local Ollama" vs "✅ Connected to OpenAI Cloud"
|
||
- Verifiable in DevTools (Max checks for 0 external API calls)
|
||
- Users can see and trust where their data goes
|
||
|
||
### Critical Success Moments
|
||
|
||
**Moment 1: First Title Suggestion Accepted**
|
||
- **Trigger:** User writes 50+ words without title
|
||
- **Interaction:** Toast appears → User clicks "View" → Sees 3 relevant suggestions
|
||
- **Success Metric:** User accepts suggestion (>60% acceptance target)
|
||
- **User Thought:** "Wow, that saved me time!"
|
||
- **Failure:** Suggestions irrelevant → User dismisses permanently
|
||
|
||
**Moment 2: Memory Echo "Aha!" Discovery**
|
||
- **Trigger:** Background analysis finds strong connection (cosine >0.75)
|
||
- **Interaction:** Notification shows 2 connected notes side-by-side
|
||
- **Success Metric:** User clicks "View Connection" (>40% CTR target)
|
||
- **User Thought:** "I hadn't seen that link before!"
|
||
- **Failure:** Connection feels random → User clicks 👎 or disables feature
|
||
|
||
**Moment 3: Semantic Search Finds the Unfindable**
|
||
- **Trigger:** User searches naturally (not exact keywords)
|
||
- **Interaction:** Results show with "Semantic Match" badge
|
||
- **Success Metric:** Semantic result in top 3 (>30% of complex searches)
|
||
- **User Thought:** "How did it find that? I searched for X, not Y!"
|
||
- **Failure:** Doesn't find what exists → User returns to Ctrl+F
|
||
|
||
**Moment 4: Privacy Verification (Max's Journey)**
|
||
- **Trigger:** Privacy-conscious user selects Ollama
|
||
- **Interaction:** Checks DevTools → Confirms 0 external API calls
|
||
- **Success Metric:** Trust established, continues using AI features
|
||
- **User Thought:** "Good, they kept their word. My data stays local."
|
||
- **Failure:** Any data leak → Uninstalls immediately
|
||
|
||
### Experience Principles
|
||
|
||
**Guiding Principles for All UX Decisions:**
|
||
|
||
**1. Capture First, Organize Later**
|
||
- Content comes before title
|
||
- AI organizes in background, never intrusive during capture
|
||
- "Zero friction" for creation
|
||
- **Implication:** No AI processing blocks note creation
|
||
|
||
**2. Contextual, Not Constant**
|
||
- AI features appear only when relevant
|
||
- No permanent AI toolbar (overwhelming)
|
||
- Temporary toast notifications with "Not now" option
|
||
- Single-interaction rule (only one AI prompt at a time)
|
||
- **Implication:** Prioritize which AI feature to show if multiple triggered
|
||
|
||
**3. Hybrid by Design**
|
||
- Keywords AND semantic mixed (user doesn't distinguish)
|
||
- Local AND cloud providers (user chooses)
|
||
- Manual AND auto (user controls automation level)
|
||
- **Implication:** Don't expose complexity, blend approaches seamlessly
|
||
|
||
**4. Transparent Control**
|
||
- Every AI feature has granular ON/OFF
|
||
- Connection status indicators (local vs cloud)
|
||
- Feedback 👍👎 visible and impactful
|
||
- Settings explain what's happening
|
||
- **Implication:** Users feel in control, not "spied on by AI"
|
||
|
||
**5. Progressive Disclosure**
|
||
- Simple by default, powerful when needed
|
||
- Basic usage: Just capture notes
|
||
- Advanced usage: Customize AI thresholds, frequency, providers
|
||
- **Implication:** Don't overwhelm new users with settings
|
||
|
||
**6. Graceful Degradation**
|
||
- If AI fails, core note-taking still works
|
||
- Fallback to alternative provider automatically
|
||
- User-friendly error messages (no technical jargon)
|
||
- **Implication:** AI enhances, doesn't block core functionality
|
||
|
||
---
|
||
|
||
## Desired Emotional Response
|
||
|
||
### Primary Emotional Goals
|
||
|
||
**Core Emotional Reaction:** "Wow, Memento understands my knowledge better than I do!"
|
||
|
||
The defining emotional moment occurs when Memory Echo reveals an invisible connection:
|
||
> 💡 *"I noticed something..."*
|
||
> *"You noted `[Node.js performance tips]` in January and `[Next.js optimization]` this week. These notes are connected."*
|
||
|
||
**User's Internal Monologue:**
|
||
- "I hadn't made that connection!" (Surprise)
|
||
- "That's brilliant!" (Admiration)
|
||
- "Memento is smarter than me!" (Trust in AI)
|
||
|
||
**This is THE differentiator** from Google Keep/Notion which lack proactive intelligence.
|
||
|
||
**Primary Emotional Goal:** Create recurring "Aha!" moments where users feel the AI is genuinely helpful, not intrusive.
|
||
|
||
### Emotional Journey Mapping
|
||
|
||
Based on the 4 User Journeys from the PRD, the emotional progression:
|
||
|
||
**Stage 1: First Discovery - Curiosity**
|
||
- *Opening Memento:* "Ok, a notes app. Standard."
|
||
- *First capture:* "Fast, it works. Good."
|
||
- *No surprise or wow yet* - Just solid functionality
|
||
|
||
**Stage 2: First AI Interaction - Interest**
|
||
- *Toast "I have 3 title ideas...":* "Oh? What's this?"
|
||
- *Relevant suggestions:* "Hey, that's actually pretty good!" (Positive)
|
||
- *Applying title:* "Cool, saved time."
|
||
|
||
**Stage 3: Memory Echo - THE "Aha!" Moment** ⭐
|
||
- *Notification "I noticed something...":* "What's this about?"
|
||
- *Seeing 2 connected notes:* "WOAH! I never saw that link!" (Surprise)
|
||
- *Click "View Connection":* "Memento understands my knowledge better than I do!" (Trust)
|
||
|
||
**Stage 4: Trust Building - Confidence**
|
||
- *Granular AI Settings:* "I can control everything. Nice."
|
||
- *Ollama Local (Max):* "Zero external calls. Perfect!"
|
||
- *Feedback 👍👎:* "My opinion matters. The AI learns."
|
||
|
||
**Stage 5: Long-term - Satisfaction**
|
||
- *Finding the unfindable:* "Thanks Memento, you saved me."
|
||
- *Less mental load:* "Finally, I'm organized without effort."
|
||
|
||
### Micro-Emotions
|
||
|
||
Subtle but critical emotional states that determine success:
|
||
|
||
**1. Trust vs. Skepticism** ✅ CRITICAL
|
||
- **Sophie (Skeptic):** "AI will spam me or get things wrong."
|
||
- **Transformation:** 👎 feedback → "Why?" modal → AI learns → "Ok, it listens to me."
|
||
- **Target Micro-emotion:** **Trust building through transparency**
|
||
|
||
**2. Control vs. Overwhelm** ✅ CRITICAL
|
||
- **Risk:** Too many AI features = overwhelming
|
||
- **Solution:** Toast "Not now" option, granular ON/OFF settings
|
||
- **Target Micro-emotion:** **"I'm in control, not the AI"**
|
||
|
||
**3. Efficiency vs. Frustration** ✅ CRITICAL
|
||
- **Alex before Memento:** "I spend 20min finding this note!" (Frustration)
|
||
- **After Memory Echo:** "Found in 2 seconds!" (Efficiency)
|
||
- **Target Micro-emotion:** **"I'm smarter with Memento"**
|
||
|
||
**4. Surprise vs. Annoyance**
|
||
- **Risk:** Toast notifications = perceived as spam
|
||
- **Solution:** Contextual triggers (50+ words), "Don't ask for this note"
|
||
- **Target Micro-emotion:** **"Oh, that's useful!" not "Another notification..."**
|
||
|
||
**5. Privacy vs. Anxiety**
|
||
- **Max:** "Will my personal data go to the cloud?"
|
||
- **Solution:** Status indicators (✅ 100% Local Ollama), DevTools verifiable
|
||
- **Target Micro-emotion:** **"My data is safe, I'm in control"**
|
||
|
||
### Design Implications
|
||
|
||
Connecting desired emotions to specific UX design choices:
|
||
|
||
**1. Trust → Transparency**
|
||
- **UX Choice:** Visual status indicators (✅ Local Ollama | ✅ OpenAI Cloud)
|
||
- **UX Choice:** 👍👎 buttons with visible feedback ("Thanks, we're learning!")
|
||
- **UX Choice:** Settings explain WHAT the AI does (no black box)
|
||
- **Implementation:** Tooltip/badge explaining "I analyzed 150 notes to find this connection"
|
||
|
||
**2. Control → Granular Settings**
|
||
- **UX Choice:** Individual ON/OFF checkboxes for EACH AI feature
|
||
- **UX Choice:** Memory Echo frequency slider (0-3/day)
|
||
- **UX Choice:** "Don't ask for this note" respected immediately
|
||
- **Implementation:** `/settings/ai` page as most important page in product
|
||
|
||
**3. Efficiency → Instant Results**
|
||
- **UX Choice:** Semantic search < 300ms (no slow loading spinner)
|
||
- **UX Choice:** Title generation < 2s (feels instant)
|
||
- **UX Choice:** Memory Echo background processing (< 100ms UI freeze)
|
||
- **Implementation:** Skeleton screens, optimistic UI updates
|
||
|
||
**4. Positive Surprise → Contextual Triggers**
|
||
- **UX Choice:** Toast ONLY after 50+ words (not at first word)
|
||
- **UX Choice:** Memory Echo max 1/day (not spammy)
|
||
- **UX Choice:** "Exact Match | Semantic Match" badges to educate without confusing
|
||
- **Implementation:** Single-interaction rule (prioritize which AI feature to show)
|
||
|
||
**5. Security → Privacy Indicators**
|
||
- **UX Choice:** Lock icon 🔒 for Ollama local
|
||
- **UX Choice:** Clear message "Your data never leaves your device" for Ollama
|
||
- **UX Choice:** "100% Local" badge visible in Settings
|
||
- **Implementation:** Provider selection screen with clear visual distinction
|
||
|
||
### Emotional Design Principles
|
||
|
||
**Guiding Principles for Creating Desired Emotional Responses:**
|
||
|
||
**1. "Aha!" Moments Over Features**
|
||
- Prioritize discovery moments (Memory Echo) over feature quantity
|
||
- Create 1-2 memorable "Wow" moments rather than 10 mediocre features
|
||
- **Design Implication:** Invest UX effort in Memory Echo = maximum emotional ROI
|
||
|
||
**2. Trust Through Transparency**
|
||
- Never hide what the AI is doing
|
||
- Show the work ("I analyzed 150 notes to find this connection")
|
||
- **Design Implication:** Loading states, badges, tooltips explain the "why"
|
||
|
||
**3. Control Reduces Anxiety**
|
||
- Every AI feature can be disabled independently
|
||
- User chooses automation level
|
||
- **Design Implication:** AI Settings page = most important product page
|
||
|
||
**4. Speed = Intelligence**
|
||
- If it's fast, AI seems smart
|
||
- If it's slow, AI seems "dumb" or "heavy"
|
||
- **Design Implication:** Optimize performance (< 2s titles, < 300ms search) = emotional UX
|
||
|
||
**5. Fail Gracefully, Recover Quickly**
|
||
- When AI errs, UX says "Sorry, I'm learning!" not "System error"
|
||
- 👎 feedback = trust-building opportunity (not failure)
|
||
- **Design Implication:** "Why is this wrong?" modal + "Thanks for teaching me!"
|
||
|
||
**6. Contextual > Constant**
|
||
- AI features appear only when relevant
|
||
- No permanent AI toolbar (overwhelming)
|
||
- **Design Implication:** Temporary toast notifications with dismissal options
|
||
|
||
---
|
||
|
||
## UX Pattern Analysis & Inspiration
|
||
|
||
### Inspiring Products Analysis
|
||
|
||
Based on the personas (Alex, Max, Léa, Sophie) and competitive landscape, here are the key inspiring products:
|
||
|
||
**1. Google Keep** (Direct Competitor)
|
||
- **What they do well:** Ultra-fast capture, clean interface, masonry grid layout
|
||
- **What's missing:** Proactive AI, semantic search, connections between notes
|
||
- **Pattern to learn:** Simplicity of capture, Masonry layout optimization
|
||
- **Already in Memento:** MasonryGrid component exists (from component inventory)
|
||
|
||
**2. Notion** (Indirect Competitor)
|
||
- **What they do well:** Power features, databases, on-demand AI
|
||
- **What's missing:** Contextual (too complex), no proactive insights
|
||
- **Pattern to learn:** Rich text editor, slash commands
|
||
- **Not applicable:** Too complex for Memento's "zero-friction" philosophy
|
||
|
||
**3. GitHub Copilot** (AI Reference - Developers)
|
||
- **What they do well:** Non-intrusive contextual suggestions
|
||
- **Pattern inspiration:** AI appears when relevant, no permanent toolbar
|
||
- **Connection to Memento:** Contextual Smart Assistance for title suggestions
|
||
- **Key insight:** Single-interaction rule (don't overwhelm with multiple AI prompts at once)
|
||
|
||
**4. Linear** (UX Reference - Tech-Savvy Users)
|
||
- **What they do well:** Speed = intelligence perception, keyboard-first, native dark mode
|
||
- **Pattern inspiration:** Performance creates perceived intelligence
|
||
- **Connection to Memento:** < 2s title generation, < 300ms semantic search
|
||
- **Key insight:** If AI is fast, users think it's smart. If slow, it seems "dumb"
|
||
|
||
**5. Obsidian** (Notes Reference - Power Users)
|
||
- **What they do well:** Graph view (visual connections), plugin ecosystem
|
||
- **What's missing:** Proactive AI (connections are manual)
|
||
- **Pattern inspiration:** Connections between notes
|
||
- **Memento innovation:** Memory Echo = PROACTIVE connections (AI finds them, not user)
|
||
|
||
**6. Slack/Notion AI** (Anti-Pattern Reference)
|
||
- **What they do poorly:** Too frequent AI notifications = perceived as spam
|
||
- **Anti-pattern to avoid:** Insufficient contextualization
|
||
- **Connection to Memento:** Max 1 insight/day to avoid annoyance
|
||
- **Key lesson:** Restrictive frequency limits build trust
|
||
|
||
### Transferable UX Patterns
|
||
|
||
**Pattern 1: Contextual Triggers (from GitHub Copilot)**
|
||
- **Source:** Copilot suggests only when relevant, not permanently
|
||
- **Memento application:** Toast titles after 50+ words (not at first word)
|
||
- **Why it works:** Natural discovery, not overwhelming
|
||
- **Design implication:** Single-interaction rule (only one AI feature at a time)
|
||
- **Implementation:** Priority queue if multiple AI triggers fire simultaneously
|
||
|
||
**Pattern 2: Masonry Layout (from Google Keep)**
|
||
- **Source:** Google Keep uses masonry grid for notes
|
||
- **Memento application:** Already implemented in component inventory (MasonryGrid)
|
||
- **Why it works:** Space optimization, visually pleasing
|
||
- **Design implication:** Reuse existing MasonryGrid, add AI badges
|
||
- **Implementation:** AI badges on NoteCard ("Title Suggested", "Semantic Match")
|
||
|
||
**Pattern 3: Speed = Intelligence (from Linear)**
|
||
- **Source:** Linear feels "smart" because it's ultra-fast
|
||
- **Memento application:** < 2s titles, < 300ms semantic search
|
||
- **Why it works:** Fast AI = perceived intelligence
|
||
- **Design implication:** Optimistic UI, skeleton screens, background processing
|
||
- **Implementation:** Show "Generating..." only if > 1s (otherwise appears instant)
|
||
|
||
**Pattern 4: Graph Connections → Memory Echo (from Obsidian)**
|
||
- **Source:** Obsidian shows manual graph view of connections
|
||
- **Memento application:** Memory Echo PROACTIVELY reveals connections
|
||
- **Innovation:** AI finds connections, not user
|
||
- **Design implication:** Subtle notification, max 1/day, 👍👎 feedback
|
||
- **Implementation:** Background cosine similarity analysis, user-triggered dismissal
|
||
|
||
**Pattern 5: Slash Commands → Contextual Menu (from Notion)**
|
||
- **Source:** Notion uses `/` for commands
|
||
- **Memento application:** Reformulation via "..." menu on NoteCard (not slash)
|
||
- **Why different:** Slash commands too intrusive for simple notes
|
||
- **Design implication:** Contextual menu, not memorized commands
|
||
- **Implementation:** NoteCard overflow menu → "Reformulate with AI" option
|
||
|
||
### Anti-Patterns to Avoid
|
||
|
||
**Anti-Pattern 1: Too Frequent AI Notifications (Slack AI, Notion AI)**
|
||
- **Problem:** "Hey! Try this feature!" every day = spam
|
||
- **Consequence:** Users disable all AI notifications
|
||
- **Memento solution:** Contextual triggers (50+ words), max 1 insight/day
|
||
- **Design implication:** Respect "Don't ask for this note" immediately
|
||
|
||
**Anti-Pattern 2: Permanent AI Toolbar (Too Many Apps)**
|
||
- **Problem:** Toolbar with 10 AI features = overwhelming
|
||
- **Consequence:** Users ignore everything, "analysis paralysis"
|
||
- **Memento solution:** Temporary toasts, features appear when relevant
|
||
- **Design implication:** No permanent "AI Features" badge in header
|
||
|
||
**Anti-Pattern 3: Black Box AI (ChatGPT, Claude UI)**
|
||
- **Problem:** Users don't know what AI is doing with their data
|
||
- **Consequence:** Skepticism, trust erosion (Sophie persona)
|
||
- **Memento solution:** Transparency ("I analyzed 150 notes"), explanatory badges
|
||
- **Design implication:** Tooltips, badges, status indicators explain "why"
|
||
|
||
**Anti-Pattern 4: Slow Loading Spinners (Legacy Apps)**
|
||
- **Problem:** 5+ second spinner = AI seems "slow" or "dumb"
|
||
- **Consequence:** Users think "not better than manual"
|
||
- **Memento solution:** < 2s titles, < 300ms search = perceived intelligence
|
||
- **Design implication:** Skeleton screens, optimistic UI, background jobs
|
||
|
||
**Anti-Pattern 5: Hidden AI Settings (Too Many SaaS)**
|
||
- **Problem:** AI settings buried 3 levels deep in obscure menu
|
||
- **Consequence:** Users don't know how to disable, frustration
|
||
- **Memento solution:** `/settings/ai` page visible, link in header
|
||
- **Design implication:** AI Settings = most important page in product
|
||
|
||
### Design Inspiration Strategy
|
||
|
||
**ADOPT (Take as-is):**
|
||
|
||
1. **Masonry Layout (Google Keep)**
|
||
- **Why:** Already implemented, works well
|
||
- **Usage:** Reuse existing MasonryGrid component
|
||
- **Addition:** AI badges on NoteCard ("Title Suggested", "Semantic Match")
|
||
|
||
2. **Contextual Triggers (GitHub Copilot)**
|
||
- **Why:** Non-intrusive, natural discovery
|
||
- **Usage:** Toast after 50+ words without title
|
||
- **Design:** Same pattern as Copilot - appear when relevant, not constant
|
||
|
||
3. **Speed Perception (Linear)**
|
||
- **Why:** Fast = smart
|
||
- **Usage:** < 2s title generation, < 300ms semantic search
|
||
- **Implementation:** Optimistic UI, skeleton screens, background processing
|
||
|
||
**ADAPT (Modify for Memento):**
|
||
|
||
1. **Graph View (Obsidian) → Memory Echo Card**
|
||
- **Obsidian:** Manual graph view, see all connections
|
||
- **Memento:** Proactive notification, 1 connection at a time
|
||
- **Adaptation:** Subtle vs. visual, proactive vs. manual
|
||
|
||
2. **Slash Commands (Notion) → Contextual Menu**
|
||
- **Notion:** `/` to access all features
|
||
- **Memento:** "..." menu on NoteCard for reformulation
|
||
- **Adaptation:** No commands to memorize, discovery via UI
|
||
|
||
3. **AI Sidebar (ChatGPT) → Toast + Settings**
|
||
- **ChatGPT:** Permanent sidebar with AI chat
|
||
- **Memento:** Temporary toasts + granular Settings page
|
||
- **Adaptation:** Non-intrusive vs. always-visible, contextual vs. general
|
||
|
||
**AVOID (Anti-patterns to NOT reproduce):**
|
||
|
||
1. ❌ **Frequent AI notifications** (Slack/Notion AI) → Max 1 insight/day
|
||
2. ❌ **Permanent AI toolbar** (Too many apps) → Temporary toasts
|
||
3. ❌ **Black box** (ChatGPT) → Full transparency
|
||
4. ❌ **Slow spinners** (Legacy) → Optimistic UI
|
||
5. ❌ **Hidden settings** (Obscure SaaS) → Visible `/settings/ai` page
|
||
|
||
**Summary Strategy:**
|
||
- **Learn** from Google Keep's simplicity + Copilot's proactivity
|
||
- **Innovate** with Memory Echo (no one has proactive connections)
|
||
- **Avoid** Slack/Notion AI mistakes (too intrusive)
|
||
- **Prioritize** speed (Linear) for perceived intelligence
|
||
|
||
---
|
||
|
||
## Design System Foundation
|
||
|
||
### Design System Choice
|
||
|
||
**Existing Design System:** Radix UI + Tailwind CSS 4
|
||
|
||
Memento already has a proven design system in place. No need to change - we'll extend it for Phase 1 AI features.
|
||
|
||
**Current Stack:**
|
||
- **UI Primitives:** Radix UI (accessible, unstyled components)
|
||
- **Styling:** Tailwind CSS 4 (utility-first framework)
|
||
- **Icons:** Lucide React
|
||
- **Layout:** Muuri (masonry), @dnd-kit (drag & drop)
|
||
|
||
**This is a "Themeable System" approach** - maximum flexibility with proven foundation.
|
||
|
||
### Rationale for Selection
|
||
|
||
**1. Development Speed** ⚡
|
||
- **Timeline constraint:** 8-12 weeks for MVP
|
||
- **20+ existing components:** NoteCard, LabelSelector, MasonryGrid already built
|
||
- **Focus on AI logic:** Don't waste time on basic UI components
|
||
- **Result:** Ship Phase 1 faster, concentrate on innovation (Memory Echo)
|
||
|
||
**2. Accessibility-First** ♿
|
||
- **WCAG 2.1 AA compliance:** Radix UI provides this out-of-the-box
|
||
- **11 accessibility NFRs:** Keyboard nav, ARIA, focus management included
|
||
- **Screen reader support:** Critical for "Announce AI-generated content" (NFR-A11Y-002)
|
||
- **Result:** Meet legal requirements without custom ARIA work
|
||
|
||
**3. Customization Flexibility** 🎨
|
||
- **Tailwind utilities:** Rapid styling for new AI components
|
||
- **Radix primitives:** Unstyled = full control over appearance
|
||
- **Consistent + unique:** Match existing look while differentiating AI features
|
||
- **Result:** Coherent UX, AI features feel integrated (not bolted-on)
|
||
|
||
**4. Long-Term Maintenance** 🔧
|
||
- **Active communities:** Radix & Tailwind have excellent maintenance
|
||
- **Industry standards:** Not risking abandoned libraries
|
||
- **Future-proof:** Compatible with Next.js 16, React 19, TypeScript 5
|
||
- **Result:** Safe technical choice for years to come
|
||
|
||
**5. Performance** 🚀
|
||
- **Tree-shakeable:** Import only used components (NFR-PERF-007: < 200KB bundle)
|
||
- **Tailwind purge:** Automatic CSS removal (only used styles in bundle)
|
||
- **RSC compatible:** Works with React Server Components (Next.js App Router)
|
||
- **Result:** Fast load times = perceived AI intelligence
|
||
|
||
### Implementation Approach
|
||
|
||
**Strategy: Extended Design System**
|
||
|
||
**1. Reuse 100% of Existing Components**
|
||
- NoteCard, MasonryGrid, LabelSelector, Header, Sidebar - all stay
|
||
- **No redesign:** Maintain visual consistency for current users
|
||
- **AI enhancements:** Add badges, indicators, states to existing components
|
||
|
||
**2. Create 7 New AI-Specific Components**
|
||
|
||
| Component | Purpose | Radix Primitive | Timeline |
|
||
|-----------|---------|-----------------|----------|
|
||
| **AIToast** | Contextual notification for title suggestions | `Toast` | Week 2 |
|
||
| **TitleSuggestions** | Dropdown with 3 AI title options | `DropdownMenu` | Week 2 |
|
||
| **MemoryEchoCard** | Card displaying 2 connected notes | Custom + `Dialog` | Week 4 |
|
||
| **ReformulationModal** | Paragraph selection + reformulation UI | `Dialog` | Week 3 |
|
||
| **AISettingsPanel** | Granular ON/OFF switches for AI features | Form + `Switch` | Week 5 |
|
||
| **SemanticBadge** | "Exact Match \| Semantic Match" indicator | Custom | Week 3 |
|
||
| **ProviderIndicator** | "✅ Local Ollama \| ✅ OpenAI Cloud" status | Custom | Week 1 |
|
||
|
||
**3. Define AI Design Tokens**
|
||
|
||
```css
|
||
/* AI-specific colors (Tailwind config extension) */
|
||
--ai-primary: #8B5CF6; /* Purple - AI intelligence */
|
||
--ai-accent: #3B82F6; /* Blue - semantic matches */
|
||
--ai-success: #10B981; /* Green - positive feedback */
|
||
--ai-warning: #F59E0B; /* Yellow - processing states */
|
||
--ai-error: #EF4444; /* Red - errors, negative feedback */
|
||
|
||
/* AI-specific spacing */
|
||
--ai-toast-margin: 1rem; /* Toast positioning */
|
||
--ai-card-gap: 1.5rem; /* Gap between Memory Echo notes */
|
||
|
||
/* AI-specific animations */
|
||
@keyframes ai-fade-in {
|
||
from { opacity: 0; transform: translateY(8px); }
|
||
to { opacity: 1; transform: translateY(0); }
|
||
}
|
||
|
||
@keyframes ai-scale-up {
|
||
from { opacity: 0; transform: scale(0.98); }
|
||
to { opacity: 1; transform: scale(1); }
|
||
}
|
||
```
|
||
|
||
**4. Component Hierarchy (Extended)**
|
||
|
||
```
|
||
Existing Components (Keep)
|
||
├── Layout
|
||
│ ├── Header → HeaderWrapper → UserNav
|
||
│ │ └── ADD: ProviderIndicator (new)
|
||
│ ├── Sidebar
|
||
│ └── MasonryGrid
|
||
│ └── NoteCard (enhanced)
|
||
│ ├── ADD: SemanticBadge (new)
|
||
│ └── ADD: ReformulationMenu (new)
|
||
│
|
||
New AI Components
|
||
├── AIToast (contextual notification)
|
||
├── TitleSuggestions (dropdown)
|
||
├── MemoryEchoCard (proactive insights)
|
||
├── ReformulationModal (paragraph AI)
|
||
└── AISettingsPanel (granular control)
|
||
```
|
||
|
||
### Customization Strategy
|
||
|
||
**Brand Differentiation (Phase 1 - Minimal):**
|
||
|
||
**1. Color Strategy**
|
||
- **Purple (#8B5CF6)** = Primary AI color (intelligence, differentiation)
|
||
- **Keep existing note colors:** Red, orange, yellow, green, teal, blue, purple, pink, gray
|
||
- **AI badge color:** Blue gradient (#3B82F6 → #60A5FA) for semantic matches
|
||
- **Rationale:** Purple = "AI is special but not alienating"
|
||
|
||
**2. Typography (No Change)**
|
||
- **System font stack** (Tailwind default)
|
||
- **Reason:** Fast loading, familiar to users, zero-config
|
||
- **AI text:** Same fonts, semantic meaning via color + icon
|
||
|
||
**3. Spacing (No Change)**
|
||
- **Tailwind spacing scale:** 4px base unit (4, 8, 12, 16, 24, 32...)
|
||
- **AI components:** Use existing scale for consistency
|
||
- **Rationale:** Maintain visual rhythm, not "another design language"
|
||
|
||
**4. Component Shape (Consistent)**
|
||
- **Border radius:** Match NoteCard (likely `rounded-md`)
|
||
- **Shadows:** Match existing cards (elevation system)
|
||
- **AI components:** Same shape language = feeling of integration
|
||
|
||
**5. Animation Standards**
|
||
|
||
| Animation | Duration | Easing | Use Case |
|
||
|-----------|----------|--------|----------|
|
||
| **ai-fade-in** | 200ms | ease-out | Toast appearance |
|
||
| **ai-slide-up** | 250ms | ease-out | Suggestions dropdown |
|
||
| **ai-scale-up** | 150ms | ease-out | Memory Echo card |
|
||
| **ai-pulse** | 2s | ease-in-out | Provider connection status |
|
||
|
||
**Rationale:** Subtle, fast animations = "AI is snappy and responsive"
|
||
|
||
---
|
||
|
||
## Core User Experience with Notebooks
|
||
|
||
### Defining Experience: Memory Echo in Notebook Context
|
||
|
||
**The Core Interaction that Makes Memento Special:**
|
||
|
||
> **"Memento reveals connections between my notes (within notebooks) that I hadn't seen"**
|
||
|
||
Every successful product has a defining experience - the interaction that, if nailed, makes everything else follow.
|
||
|
||
**Famous examples:**
|
||
- Tinder: "Swipe to match with people"
|
||
- Snapchat: "Share photos that disappear"
|
||
- Instagram: "Share perfect moments with filters"
|
||
- Spotify: "Discover and play any song instantly"
|
||
|
||
**For Memento Phase 1, the defining experience is:**
|
||
|
||
**Memory Echo:** "I noticed something..." - The AI proactively reveals a connection between notes within the user's current notebook context that they hadn't discovered.
|
||
|
||
This is THE moment users will describe to their friends:
|
||
> *"You have to see this! Memento showed me that I had two related notes from January and this week that I hadn't connected!"*
|
||
|
||
This is the "Aha!" moment that creates the emotion: "Wow, that's clever!" (from Emotional Response analysis).
|
||
|
||
**Critical Innovation:** Memory Echo operates within **Notebook context** by default, making connections more relevant and scoped to the user's current work area.
|
||
|
||
### User Mental Model
|
||
|
||
**How users currently think about note-taking:**
|
||
|
||
**Current Mental Model (Before Memento Phase 1):**
|
||
```
|
||
My notes = Disconnected silos
|
||
├── I capture ideas
|
||
├── I try to remember them later
|
||
└── I lose connections between ideas (human = limited)
|
||
```
|
||
|
||
**Problems:**
|
||
- "I noted that somewhere, but I don't remember where"
|
||
- "I know I thought about that, but I can't find the note"
|
||
- "My ideas are connected, but my notes don't show it"
|
||
|
||
**Enhanced Mental Model (With Memento Notebooks + Memory Echo):**
|
||
```
|
||
My Notes = Organized Network
|
||
├── I organize into Notebooks (Work, Personal, Projects...)
|
||
├── Memento organizes within each Notebook in background
|
||
└── Memento reveals invisible connections (Notebook-scoped)
|
||
```
|
||
|
||
**Transformation:**
|
||
- **Before:** "I search my notes" (active, effort)
|
||
- **After:** "Memento finds what I forgot" (proactive, surprise)
|
||
- **Notebooks provide:** Contextual scope = more relevant connections
|
||
|
||
**Notebook Mental Model:**
|
||
- **Physical analogy:** Real notebooks (Work, Personal, Ideas...)
|
||
- **Clear separation:** Work vs. Personal = mental boundaries
|
||
- **Scalability:** 1000+ notes distributed across notebooks = manageable
|
||
- **Natural organization:** Like having different physical notebooks for different purposes
|
||
|
||
**User Expectations:**
|
||
1. **Fast capture** = Instant (Google Keep style)
|
||
2. **Organized structure** = Notebooks provide organization
|
||
3. **Proactive discovery** = Memory Echo within current notebook context
|
||
4. **Control** = Can switch notebooks, view global connections optionally
|
||
|
||
**Potential Confusions:**
|
||
- "Does Memento read all my notes?" → Yes, but locally (privacy-first, Ollama)
|
||
- "How does it know they're connected?" → Explanation: Semantic embeddings
|
||
- "Is it always accurate?" → No, hence 👎 feedback learning system
|
||
- "Are connections across notebooks or within?" → Within by default, optional global view
|
||
|
||
### Success Criteria
|
||
|
||
**When does the defining experience "just work"?**
|
||
|
||
**1. "It Just Works" - Magic Happens**
|
||
- **Trigger:** Background analysis finds cosine similarity > 0.75 within current notebook
|
||
- **Interaction:** "I noticed something..." notification appears
|
||
- **Success:** User clicks "View Connection" (> 40% CTR target from PRD)
|
||
- **Feedback:** Two connected notes clearly show semantic link
|
||
- **User thought:** "Oh wow! I hadn't seen that connection!"
|
||
- **Notebook context:** Connection within current notebook = more relevant
|
||
|
||
**2. Perceived Intelligence - AI Feels Smart**
|
||
- **Trigger:** Memory Echo notification appears
|
||
- **Success:** < 100ms UI freeze (feels instantaneous)
|
||
- **Feedback:** No slow loading spinner (perceived as "dumb")
|
||
- **User thought:** "Wow, that's instant, Memento is smart!"
|
||
- **Notebook enhancement:** Scoped context = appears more intelligent
|
||
|
||
**3. Relevant, Not Spammy - Right Moment, Right Place**
|
||
- **Trigger:** Max 1 insight/day (configurable 0-3)
|
||
- **Success:** User thinks "That's useful" not "Another notification..."
|
||
- **Feedback:** User doesn't disable Memory Echo feature
|
||
- **User thought:** "Interesting, thanks Memento!"
|
||
- **Notebook relevance:** "This helps with my current work in this notebook"
|
||
|
||
**4. Trust Building - Confidence Establishes**
|
||
- **Trigger:** First Memory Echo connection
|
||
- **Success:** Connection IS relevant (not hallucination)
|
||
- **Feedback:** 👍👎 buttons available and respected
|
||
- **User thought:** "I'm in control, no problem if it's wrong"
|
||
- **Notebook control:** User can switch notebooks to find different connections
|
||
|
||
**5. Notebook Organization - Structure Feels Natural**
|
||
- **Trigger:** User creates/accesses notes in specific notebooks
|
||
- **Success:** Notes automatically organized by notebook context
|
||
- **Feedback:** Sidebar shows notebook hierarchy clearly
|
||
- **User thought:** "Finally, my work is organized!"
|
||
- **Inbox concept:** Unassigned notes go to "Inbox" notebook (default)
|
||
|
||
**Success Indicators:**
|
||
- ✅ > 40% CTR on "View Connection" (PRD requirement)
|
||
- ✅ > 3:1 👎 ratio (quality threshold)
|
||
- ✅ < 1% users disable Memory Echo (not frustrating)
|
||
- ✅ User quote: "Memento surprised me by finding X in my Work notes!"
|
||
- ✅ Notebook adoption: > 80% users create custom notebooks beyond "Inbox"
|
||
|
||
### Novel UX Patterns
|
||
|
||
**Pattern Analysis:**
|
||
|
||
**Memory Echo = Novel Pattern in Note-Taking**
|
||
|
||
**Current Market State:**
|
||
- **Google Keep:** No AI proactive features at all
|
||
- **Notion:** On-demand AI (slash commands), not proactive
|
||
- **Obsidian:** Manual graph view (no AI)
|
||
- **Roam Research:** Graph view, no proactive insights
|
||
- **Evernote:** Notebook organization exists, but no AI connections
|
||
|
||
**Memento Innovation:**
|
||
- **FIRST** to combine:
|
||
- **Notebook organization** (familiar structure)
|
||
- **Semantic search** (embeddings)
|
||
- **Proactive notifications** (Memory Echo)
|
||
- **Feedback learning** (👎 system)
|
||
- **Privacy-first** (local processing option)
|
||
- **Notebook-scoped insights** (contextual relevance)
|
||
|
||
**This is HYBRID innovation:**
|
||
- **Base:** Notebook organization (Evernote-like) → **Established**
|
||
- **Base:** Graph connections (Obsidian-like) → **Established**
|
||
- **Innovation:** AI proactive + feedback loop + notebook scope → **Novel**
|
||
|
||
**User Education:**
|
||
|
||
**Familiar Metaphors:**
|
||
- "Like an assistant thinking about your notes while you sleep"
|
||
- "Like Google Photos grouping photos, but for your ideas"
|
||
- "Like Spotify Discover Weekly, but for your notes within each notebook"
|
||
|
||
**Progressive Onboarding:**
|
||
1. User captures notes in "Inbox" (familiar, single notebook)
|
||
2. Title suggestions toast (discovery of AI)
|
||
3. Create custom "Work" notebook (structure discovery)
|
||
4. Memory Echo appears in "Work" context (surprise "Aha!")
|
||
5. Granular settings (control discovery)
|
||
|
||
**Notebook-Specific Education:**
|
||
- "Each notebook is like a separate world - Memento finds connections within it"
|
||
- "Switch notebooks to discover connections in different contexts"
|
||
- "Use 'Inbox' for quick capture, organize into notebooks later"
|
||
|
||
### Experience Mechanics
|
||
|
||
**Detailed breakdown of Memory Echo interaction within Notebook context:**
|
||
|
||
#### 1. Initiation (Trigger)
|
||
|
||
**Backend (Silent, Invisible):**
|
||
- **Timing:** Every hour (cron job)
|
||
- **Scope:** Analyze embeddings within **current notebook**
|
||
- **Process:**
|
||
1. Fetch all note embeddings from **current notebook**
|
||
2. Calculate cosine similarity matrix (notebook-scoped)
|
||
3. Filter: similarity > 0.75 (threshold)
|
||
4. Sort by score descending
|
||
5. Fetch top 1 connection
|
||
- **Duration:** < 100ms UI freeze (background job)
|
||
- **Notebook isolation:** Each notebook has independent similarity analysis
|
||
|
||
**Frontend (User-Visible):**
|
||
- **Trigger:** Notification appears (no "Run Memory Echo" button)
|
||
- **Timing:** Max 1 time/day (configurable 0-3)
|
||
- **Condition:** At least 2 notes with embeddings in **current notebook**
|
||
- **Notebook indicator:** Notification shows which notebook: "💡 I noticed something in your **Work** notes..."
|
||
|
||
**Visual:**
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ 💡 I noticed something... │
|
||
│ │
|
||
│ In your "Work" notes: │
|
||
│ │
|
||
│ You noted "Node.js performance" │
|
||
│ and "Next.js optimization". These │
|
||
│ notes are connected. │
|
||
│ │
|
||
│ [View Connection] [Dismiss] [×] │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
#### 2. Interaction (User Actions)
|
||
|
||
**Option A: "View Connection" (Success Path)**
|
||
1. **Click** → MemoryEchoCard modal/panel opens
|
||
2. **Display:** 2 notes side-by-side (desktop) or stacked (mobile)
|
||
3. **Visualization:**
|
||
- Note A: "Node.js performance tips"
|
||
- Note B: "Next.js optimization"
|
||
- Highlight: Connected words/phrases emphasized
|
||
- Badge: "93% match" (cosine similarity)
|
||
- **Notebook context:** "From: Work notebook"
|
||
4. **Available actions:**
|
||
- "Link these notes" (create shared label?)
|
||
- 👍 "This is helpful" (positive feedback)
|
||
- 👎 "Not relevant" (negative feedback)
|
||
- [×] Close
|
||
|
||
**Option B: "Dismiss" (Neutral Path)**
|
||
1. **Click** → Notification disappears
|
||
2. **Feedback:** "Ok, maybe next time"
|
||
3. **No data stored** (no learning)
|
||
|
||
**Option C: [×] Close (Same as Dismiss)**
|
||
1. **Click** → Notification disappears
|
||
2. **No feedback**
|
||
|
||
#### 3. Feedback (Learning Loop)
|
||
|
||
**Positive Feedback (👍):**
|
||
- **Action:** User clicks 👎 after "View Connection"
|
||
- **System response:**
|
||
- Toast: "Thanks! We'll show more insights like this in **Work** notes."
|
||
- Data: Store +1 score for this connection type within notebook context
|
||
- Learning: Increase cosine threshold for this connection type in this notebook
|
||
- **Future:** More of this connection type in this notebook
|
||
|
||
**Negative Feedback (👎):**
|
||
- **Action:** User clicks 👎 after "View Connection"
|
||
- **System response:**
|
||
- Modal: "Why wasn't this relevant?" (optional)
|
||
- "Wrong connection"
|
||
- "Not useful right now"
|
||
- "Too many notifications"
|
||
- "Wrong notebook context"
|
||
- Toast: "Thanks for teaching us! We'll improve."
|
||
- Data: Store -1 score for this connection type in this notebook
|
||
- Learning: Decrease cosine threshold for this connection type in this notebook
|
||
- **Future:** Less of this connection type in this notebook
|
||
|
||
**No Feedback (Dismiss/Close):**
|
||
- **No learning** (neutral)
|
||
- **Counts as "non-action"** in analytics
|
||
|
||
#### 4. Completion & Notebook Context
|
||
|
||
**Success Path Completed:**
|
||
- **Outcome:** User discovered invisible connection within notebook
|
||
- **Next steps:**
|
||
- Can link notes (action: create shared label)
|
||
- Can continue work in current notebook
|
||
- **Option:** "See connections in other notebooks" (toggle global)
|
||
- Next Memory Echo: Tomorrow (max 1/day)
|
||
|
||
**Switching Notebooks:**
|
||
- **User action:** Click different notebook in sidebar
|
||
- **System response:**
|
||
- Switch view to that notebook's masonry grid
|
||
- Update Memory Echo context to new notebook
|
||
- Background analysis now scopes to new notebook
|
||
- **Notification:** "💡 Switched to **Personal** notebook"
|
||
|
||
**Global Connections (Optional Feature):**
|
||
- **User action:** Toggle "Show connections across all notebooks"
|
||
- **System response:**
|
||
- Memory Echo scope expands beyond current notebook
|
||
- Notification: "💡 I noticed something **across your notes**..."
|
||
- Badge: "Global connection" vs. "Notebook connection"
|
||
- **Use case:** User wants serendipitous cross-notebook discoveries
|
||
|
||
**Dismiss Path Completed:**
|
||
- **Outcome:** Notification closed, no learning
|
||
- **Next steps:**
|
||
- Continue normal capture in current notebook
|
||
- Next Memory Echo: Tomorrow (frequency unchanged)
|
||
|
||
**Settings Path (Control):**
|
||
- **User navigates:** `/settings/ai`
|
||
- **Actions:**
|
||
- Change "Memory Echo frequency" (1 → 0 to disable)
|
||
- "Notebook scope" toggle: Current notebook vs. All notebooks
|
||
- Per-notebook frequency: Work = daily, Personal = weekly
|
||
- **Respect:** Immediate, no "are you sure?"
|
||
|
||
---
|
||
|
||
## Visual Design Foundation
|
||
|
||
### Color System
|
||
|
||
#### Philosophy: Intelligence + Clarté
|
||
|
||
The color palette balances **AI modernity** (violet/bleu) with **content-first design** (blanc pur), ensuring user notes remain the focal point while AI interactions are clearly visible and trustworthy.
|
||
|
||
#### Core Palette
|
||
|
||
```css
|
||
/* Brand Colors */
|
||
--primary: #8B5CF6; /* Violet - IA Intelligence */
|
||
--primary-light: #A78BFA;
|
||
--primary-dark: #7C3AED;
|
||
|
||
--secondary: #3B82F6; /* Bleu - Confiance */
|
||
--secondary-light: #60A5FA;
|
||
--secondary-dark: #2563EB;
|
||
|
||
--accent: #10B981; /* Vert émeraude - Success, Positive Feedback */
|
||
```
|
||
|
||
**Rationale:**
|
||
- **Violet (#8B5CF6)**: Evokes AI creativity and intelligence, modern and tech-forward
|
||
- **Bleu (#3B82F6)**: Builds trust for privacy-conscious users, stable and professional
|
||
- **Vert (#10B981)**: Positive reinforcement for AI feedback system (👍👎), encourages engagement
|
||
|
||
#### Semantic Colors
|
||
|
||
```css
|
||
/* Functional Colors */
|
||
--success: #10B981; /* Green - Success, accepted suggestions */
|
||
--warning: #F59E0B; /* Amber - Processing states, caution */
|
||
--error: #EF4444; /* Red - Errors, rejected suggestions */
|
||
--info: #3B82F6; /* Blue - Informational */
|
||
```
|
||
|
||
#### AI-Specific Colors
|
||
|
||
```css
|
||
/* AI Feature Colors */
|
||
--ai-primary: #8B5CF6; /* Primary AI interactions */
|
||
--ai-accent: #3B82F6; /* Semantic search matches */
|
||
--ai-processing: #F59E0B; /* Background processing state */
|
||
--ai-connection: #8B5CF6; /* Memory Echo link highlights */
|
||
--ai-suggestion: #A78BFA; /* Suggested titles, reformulations */
|
||
```
|
||
|
||
**Usage:**
|
||
- **Memory Echo cards**: Purple border (`--ai-connection`) + subtle purple background
|
||
- **Title suggestions**: Purple text (`--ai-suggestion`) for AI-generated options
|
||
- **Semantic search badges**: Blue (`--ai-accent`) for "Semantic Match" indicators
|
||
- **Processing states**: Amber spinner (`--ai-processing`) during embedding generation
|
||
|
||
#### Neutral Colors
|
||
|
||
```css
|
||
/* Background & Surface */
|
||
--background: #FFFFFF; /* Pure white - content focus */
|
||
--surface: #F9FAFB; /* Very light gray - subtle separation */
|
||
--surface-elevated: #FFFFFF; /* Cards, modals (elevated on white) */
|
||
|
||
/* Text Colors */
|
||
--text-primary: #111827; /* Nearly black - main content */
|
||
--text-secondary: #6B7280; /* Medium gray - metadata, secondary */
|
||
--text-muted: #9CA3AF; /* Light gray - timestamps, hints */
|
||
|
||
/* Borders & Dividers */
|
||
--border: #E5E7EB; /* Light gray - subtle separation */
|
||
--border-hover: #D1D5DB; /* Medium gray - interactive states */
|
||
```
|
||
|
||
**Design Philosophy:**
|
||
- **Blanc pur background**: Ensures notes are the hero, not the interface
|
||
- **Subtle surfaces**: Light grays (#F9FAFB) provide visual hierarchy without distraction
|
||
- **High contrast text**: Meets WCAG AA standards (4.5:1 minimum contrast ratio)
|
||
|
||
#### Accessibility Compliance
|
||
|
||
✅ **WCAG 2.1 Level AA**:
|
||
- All text-to-background contrast ratios ≥ 4.5:1
|
||
- Large text (18px+) contrast ≥ 3:1
|
||
- Interactive elements (buttons, links) have visible focus states
|
||
- Color not used as the only visual means of conveying information
|
||
|
||
✅ **Color Independence**:
|
||
- AI features use color + icon + text label (triple coding)
|
||
- Memory Echo: Purple + 💡 icon + "I noticed..." text
|
||
- Semantic badges: Blue + "Semantic Match" label + dashed underline
|
||
|
||
---
|
||
|
||
### Typography System
|
||
|
||
#### Philosophy: Performance + Lisibilité
|
||
|
||
Using **system fonts** eliminates external font loading (zero DevOps, maximum performance) while ensuring native OS optimization and multilingual support (French accents, emojis).
|
||
|
||
#### Font Family Stack
|
||
|
||
```css
|
||
--font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||
sans-serif;
|
||
```
|
||
|
||
**Rationale:**
|
||
- **Performance**: No external HTTP requests, instant rendering
|
||
- **Native feel**: Each OS shows its optimized font (San Francisco on Mac, Segoe UI on Windows)
|
||
- **Multilingual**: Native support for French accents, emojis, special characters
|
||
- **Accessibility**: System fonts are designed for screen readers and zoom
|
||
|
||
#### Type Scale (Perfect Fourth - 1.333)
|
||
|
||
```css
|
||
/* Font Sizes */
|
||
--text-xs: 0.75rem; /* 12px - Captions, metadata */
|
||
--text-sm: 0.875rem; /* 14px - Secondary text, labels, helper text */
|
||
--text-base: 1rem; /* 16px - Body content (WCAG recommended minimum) */
|
||
--text-lg: 1.125rem; /* 18px - Lead paragraphs, emphasized content */
|
||
--text-xl: 1.25rem; /* 20px - Note titles in cards */
|
||
--text-2xl: 1.5rem; /* 24px - Cahier (notebook) titles in sidebar */
|
||
--text-3xl: 1.875rem; /* 30px - Page headings */
|
||
--text-4xl: 2.25rem; /* 36px - Hero text, empty states */
|
||
```
|
||
|
||
**Scale Choice**: Perfect Fourth (1.333 ratio) provides harmonious progression while maintaining distinct hierarchy levels.
|
||
|
||
#### Line Heights
|
||
|
||
```css
|
||
/* Line Spacing */
|
||
--leading-tight: 1.25; /* Headings - compact, impactful */
|
||
--leading-normal: 1.5; /* UI text, labels - standard readability */
|
||
--leading-relaxed: 1.75; /* Body content - optimal for long-form */
|
||
```
|
||
|
||
#### Font Weights
|
||
|
||
```css
|
||
--font-normal: 400; /* Body text, standard content */
|
||
--font-medium: 500; /* UI emphasis, button text */
|
||
--font-semibold: 600; /* Headings, important labels */
|
||
--font-bold: 700; /* Strong emphasis, CTAs */
|
||
```
|
||
|
||
#### Typographic Usage Guidelines
|
||
|
||
| Element | Size | Weight | Line Height | Use Case |
|
||
|---------|------|--------|-------------|----------|
|
||
| Page Headings | `text-3xl` (30px) | Semibold (600) | Tight (1.25) | Page titles, empty state headers |
|
||
| Cahier Titles | `text-2xl` (24px) | Semibold (600) | Normal (1.5) | Sidebar notebook names |
|
||
| Note Card Titles | `text-xl` (20px) | Semibold (600) | Normal (1.5) | Main note title in masonry grid |
|
||
| Lead Paragraphs | `text-lg` (18px) | Normal (400) | Relaxed (1.75) | Emphasized intro text |
|
||
| Body Content | `text-base` (16px) | Normal (400) | Relaxed (1.75) | Note content, long-form text |
|
||
| Secondary Text | `text-sm` (14px) | Normal (400) | Normal (1.5) | Metadata, timestamps, hints |
|
||
| Captions | `text-xs` (12px) | Medium (500) | Normal (1.5) | AI badges, helper text |
|
||
|
||
#### Responsive Typography
|
||
|
||
Typography scales with viewport width for optimal readability:
|
||
|
||
```css
|
||
/* Mobile-first approach */
|
||
@media (min-width: 768px) {
|
||
/* Tablet+: Increase base size slightly */
|
||
:root {
|
||
--text-base: 1.125rem; /* 18px on larger screens */
|
||
}
|
||
}
|
||
```
|
||
|
||
#### Accessibility Features
|
||
|
||
✅ **Text Zoom Support**:
|
||
- Layout supports up to 200% text zoom without horizontal scrolling
|
||
- Flexible units (rem) ensure proportional scaling
|
||
|
||
✅ **Readability**:
|
||
- Minimum body text: 16px (WCAG recommended)
|
||
- Line height: 1.75 for body content (prevents walls of text)
|
||
- Max line length: 65-75 characters for optimal reading speed
|
||
|
||
✅ **Screen Reader Optimization**:
|
||
- Semantic HTML heading hierarchy (h1 → h2 → h3)
|
||
- System fonts render consistently across assistive technologies
|
||
|
||
---
|
||
|
||
### Spacing & Layout Foundation
|
||
|
||
#### Philosophy: Balanced Density
|
||
|
||
Using an **8px grid system** provides industry-standard spacing that balances content visibility with breathing room, ensuring the interface feels neither cluttered nor wasteful.
|
||
|
||
#### Spacing Scale (8px Base Unit)
|
||
|
||
```css
|
||
/* 8px Grid Scale */
|
||
--space-0: 0; /* No spacing */
|
||
--space-1: 0.25rem; /* 4px - Micro spacing between related elements */
|
||
--space-2: 0.5rem; /* 8px - Base unit, tight grouping */
|
||
--space-3: 0.75rem; /* 12px - Compact separation */
|
||
--space-4: 1rem; /* 16px - Comfortable spacing (most common) */
|
||
--space-5: 1.25rem; /* 20px - Section separation */
|
||
--space-6: 1.5rem; /* 24px - Major component gaps */
|
||
--space-8: 2rem; /* 32px - Component grouping */
|
||
--space-10: 2.5rem; /* 40px - Page margins */
|
||
--space-12: 3rem; /* 48px - Large section separation */
|
||
--space-16: 4rem; /* 64px - Hero sections, empty states */
|
||
```
|
||
|
||
**Why 8px?**
|
||
- Industry standard (Bootstrap, Material Design, Tailwind)
|
||
- Highly divisible (16, 24, 32, 40, 48 are all multiples)
|
||
- Natural visual rhythm
|
||
- Tailwind CSS native support (spacing-2 = 8px)
|
||
|
||
#### Layout Component Spacing
|
||
|
||
**Masonry Grid (Notes within Cahiers):**
|
||
- Gap between cards: `--space-4` (16px) - comfortable separation
|
||
- Padding within cards: `--space-4` (16px) - content breathing room
|
||
- Card corner radius: `8px` (rounded-lg) - modern but not distracting
|
||
|
||
**Sidebar (Cahiers Navigation):**
|
||
- Width: `256px` (w-64) on desktop, full width on mobile
|
||
- Padding vertical: `--space-4` (16px)
|
||
- Padding horizontal: `--space-3` (12px)
|
||
- Gap between cahier items: `--space-2` (8px)
|
||
|
||
**Header (Top Bar):**
|
||
- Height: `64px` (h-16)
|
||
- Padding horizontal: `--space-4` (16px)
|
||
- Gap between search and user menu: `--space-4` (16px)
|
||
|
||
**AI Toast/Notifications:**
|
||
- Padding: `--space-4` (16px) all around
|
||
- Margin from viewport edge: `--space-4` (16px)
|
||
- Gap between toasts: `--space-3` (12px)
|
||
|
||
**Memory Echo Card:**
|
||
- Padding: `--space-6` (24px)
|
||
- Border: 2px solid `--ai-connection` (#8B5CF6)
|
||
- Corner radius: `12px` (rounded-xl) - distinctive from note cards
|
||
|
||
#### Grid System: 12 Columns (Adaptive)
|
||
|
||
**Why 12 Columns?**
|
||
- Highly flexible (divisible by 2, 3, 4, 6)
|
||
- Supports multiple layout patterns (2-col, 3-col, 4-col, 6-col)
|
||
- Industry standard (Bootstrap, Foundation, Tailwind)
|
||
|
||
**Breakpoints:**
|
||
|
||
```css
|
||
/* Tailwind Standard Breakpoints */
|
||
--breakpoint-sm: 640px; /* Mobile large */
|
||
--breakpoint-md: 768px; /* Tablet portrait */
|
||
--breakpoint-lg: 1024px; /* Desktop, laptop */
|
||
--breakpoint-xl: 1280px; /* Desktop large */
|
||
```
|
||
|
||
**Responsive Masonry Layout:**
|
||
|
||
| Screen Size | Columns | Column Width | Notes Visible |
|
||
|-------------|---------|--------------|---------------|
|
||
| Mobile (< 768px) | 1 | 100% | Single column stack |
|
||
| Tablet (768-1024px) | 2 | ~48% each | 2-column grid |
|
||
| Desktop (1024-1280px) | 3 | ~32% each | 3-column grid |
|
||
| Desktop XL (> 1280px) | 4 | ~24% each | 4-column grid |
|
||
|
||
**Notebook Sidebar Layout:**
|
||
- **Desktop (> 1024px)**: Fixed 256px sidebar on left, main content fills remaining width
|
||
- **Tablet/Mobile (< 1024px)**: Collapsible sidebar (hamburger menu) to maximize content space
|
||
|
||
#### Layout Principles
|
||
|
||
1. **Content-First Hierarchy**:
|
||
- Pure white background (`#FFFFFF`) ensures notes are focal point
|
||
- Subtle surface colors (`#F9FAFB`) separate sections without distraction
|
||
|
||
2. **Visual Rhythm**:
|
||
- Consistent 16px padding inside cards and components
|
||
- 16px gaps between masonry items for consistent whitespace
|
||
|
||
3. **Responsive Flexibility**:
|
||
- Masonry grid adapts column count based on viewport width
|
||
- Sidebar collapses on mobile to preserve screen real estate
|
||
|
||
4. **AI Feature Prominence**:
|
||
- Memory Echo cards use 24px padding (larger than note cards' 16px) for emphasis
|
||
- AI toasts float 16px from edges to ensure visibility without blocking content
|
||
|
||
5. **Accessibility Spacing**:
|
||
- Minimum touch target size: 44×44px (WCAG 2.5.5)
|
||
- Focus indicators have 2px outline with sufficient contrast
|
||
|
||
---
|
||
|
||
### Accessibility Considerations
|
||
|
||
#### Visual Accessibility
|
||
|
||
✅ **Color Contrast** (WCAG 2.1 Level AA):
|
||
- All normal text: Minimum 4.5:1 contrast ratio
|
||
- Large text (18px+): Minimum 3:1 contrast ratio
|
||
- Interactive elements: Minimum 3:1 contrast ratio
|
||
|
||
✅ **Text Scaling**:
|
||
- Layout supports 200% text zoom without horizontal scrolling
|
||
- Rem-based units ensure proportional scaling
|
||
- No fixed-width containers that break on zoom
|
||
|
||
✅ **Focus Indicators**:
|
||
- All interactive elements have visible focus states
|
||
- 2px solid outline in primary color (`#8B5CF6`)
|
||
- Focus outline offset: 2px from element
|
||
|
||
#### Color Independence
|
||
|
||
✅ **Triple Coding for AI Features**:
|
||
- **Color**: Purple/blue for AI interactions
|
||
- **Icon**: 💡 for Memory Echo, 🔍 for search, ✨ for suggestions
|
||
- **Text**: Clear labels ("I noticed something...", "Semantic Match")
|
||
|
||
✅ **Example - Memory Echo**:
|
||
- Color: Purple border + purple tint background
|
||
- Icon: 💡 lightbulb icon
|
||
- Text: "I noticed something..." headline + explanation
|
||
|
||
#### Screen Reader Support
|
||
|
||
✅ **Semantic HTML**:
|
||
- Proper heading hierarchy (h1 → h2 → h3)
|
||
- ARIA labels for custom components (Memory Echo cards, AI toasts)
|
||
- Live regions for dynamic content (AI notifications)
|
||
|
||
✅ **Example - Memory Echo Card**:
|
||
```html
|
||
<div
|
||
role="alert"
|
||
aria-live="polite"
|
||
aria-label="AI notification: Note connection discovered"
|
||
>
|
||
<div class="flex items-center gap-3">
|
||
<span aria-hidden="true">💡</span>
|
||
<h3>I noticed something...</h3>
|
||
</div>
|
||
<!-- Connection details -->
|
||
</div>
|
||
```
|
||
|
||
#### Keyboard Navigation
|
||
|
||
✅ **Full Keyboard Support**:
|
||
- Tab: Navigate through interactive elements
|
||
- Enter/Space: Activate buttons, links
|
||
- Escape: Close modals, dismiss toasts
|
||
- Arrow keys: Navigate within lists (cahiers, tags)
|
||
|
||
✅ **Visible Focus**:
|
||
- 2px purple outline on focused elements
|
||
- High contrast (4.5:1 minimum) against backgrounds
|
||
- No outline removal on focus (`outline-none` only for mouse users via `:focus-visible`)
|
||
|
||
#### Motion Sensitivity
|
||
|
||
✅ **Respects `prefers-reduced-motion`**:
|
||
- Animations disabled for users who prefer reduced motion
|
||
- Transitions: `0.2s ease-out` (gentle, not jarring)
|
||
- Memory Echo appearance: Fade-in (no slide/bounce for motion-sensitive users)
|
||
|
||
---
|
||
|
||
### Visual Foundation Strategy Summary
|
||
|
||
**Color System:**
|
||
- Intelligence-focused palette (violet/bleu) with pure white background
|
||
- AI features clearly distinguished with semantic colors
|
||
- WCAG AA compliant contrast ratios
|
||
|
||
**Typography:**
|
||
- System fonts for maximum performance and native feel
|
||
- Perfect Fourth scale (1.333) for harmonious hierarchy
|
||
- 16px base with 1.75 line height for optimal readability
|
||
- Supports French accents, emojis, and special characters
|
||
|
||
**Spacing & Layout:**
|
||
- 8px grid system for consistent visual rhythm
|
||
- 12-column adaptive layout for responsive masonry grid
|
||
- 16px component padding/gaps for balanced density
|
||
- Cahiers sidebar: 256px desktop, collapsible on mobile
|
||
|
||
**Accessibility:**
|
||
- Color independence (triple coding for AI features)
|
||
- 200% text zoom support
|
||
- Full keyboard navigation
|
||
- Screen reader optimization with semantic HTML + ARIA
|
||
|
||
This foundation ensures **consistency across all design decisions** while maintaining the "Zéro Prise de Tête" philosophy - the design system is invisible, letting users focus on their notes and AI-powered insights.
|
||
|
||
---
|
||
|
||
## Design Direction Decision
|
||
|
||
### Design Directions Explored
|
||
|
||
Three distinct design directions were evaluated for Memento Phase 1 MVP AI:
|
||
|
||
**Direction A: "Invisible IA"** (Chosen)
|
||
- Philosophy: AI is present but never intrusive - appears when needed, then recedes
|
||
- Layout: Full-screen masonry grid with minimal sidebar (256px, collapsible)
|
||
- AI Presentation: Contextual elements (toasts, hover states, dropdowns) only
|
||
- Visual Density: High (maximize note visibility)
|
||
- Color Dominance: Pure white with violet/blue accents for AI only
|
||
|
||
**Direction B: "IA Partenaire"** (Evaluated)
|
||
- Philosophy: AI as visible copilot, always present to assist
|
||
- Layout: Masonry grid + sidebar + permanent AI Panel (320px right)
|
||
- AI Presentation: Always-visible suggestions, connections, insights
|
||
- Visual Density: Medium (balance content and AI context)
|
||
- Color Dominance: White with AI-colored zones (light purple backgrounds)
|
||
|
||
**Direction C: "Hydra Contextuelle"** (Evaluated)
|
||
- Philosophy: Interface adapts dynamically to user intent
|
||
- Layout: Adaptive modes (Capture, Discovery, Focus)
|
||
- AI Presentation: Mode-specific interfaces with animated transitions
|
||
- Visual Density: Variable per mode
|
||
- Color Dominance: Adaptive white → blue → purple based on mode
|
||
|
||
### Chosen Direction
|
||
|
||
**Direction A: "Invisible IA" with Direction B Enhancement**
|
||
|
||
The chosen direction combines the **content-first minimalism** of Direction A with the **AI visibility** element from Direction B:
|
||
|
||
**Core Principles:**
|
||
1. **Content is King**: Pure white background, masonry grid fills viewport
|
||
2. **AI Contextual**: AI features appear only at relevant moments
|
||
3. **Non-Intrusive Discovery**: Memory Echo creates "Aha!" without permanent UI
|
||
4. **Progressive Enhancement**: Users discover AI features naturally through use
|
||
|
||
**Key Design Elements:**
|
||
|
||
**Layout Structure:**
|
||
```
|
||
┌─────────────────────────────────────────────────┐
|
||
│ Header (64px) │
|
||
│ [Logo] [Search] [✨ AI: On ▼] [User] │
|
||
└─────────────────────────────────────────────────┘
|
||
┌──────────┬──────────────────────────────────────┐
|
||
│ Cahiers │ Masonry Grid (Notes) │
|
||
│ Sidebar │ │
|
||
│ (256px) │ [Note Card] [Note Card] [Note Card]│
|
||
│ │ [Note Card] [Note Card] │
|
||
│ Inbox │ │
|
||
│ Work │ │
|
||
│ Personal │ │
|
||
│ + New │ │
|
||
└──────────┴──────────────────────────────────────┘
|
||
```
|
||
|
||
**AI Feature Integration:**
|
||
|
||
1. **Memory Echo** ⭐ (Defining "Aha!" Experience)
|
||
- **Presentation**: Floating toast notification (bottom-right)
|
||
- **Appearance**: Fade-in with subtle purple border
|
||
- **Content**: "💡 I noticed something in your **Work** notes..."
|
||
- **Interaction**: Dismissible card with 👍👎 feedback
|
||
- **Persistence**: Auto-dismiss after 30s, or manual close
|
||
- **No permanent space**: Appears, delivers value, recedes
|
||
|
||
2. **Title Suggestions** (Feature 1)
|
||
- **Trigger**: On note title focus/blur after content entry
|
||
- **Presentation**: Dropdown menu below title field
|
||
- **Content**: 3 AI-generated title options with ✨ indicator
|
||
- **Interaction**: Click to select, ESC to dismiss
|
||
- **Visual**: Purple text for AI suggestions, hover state with bg-purple-50
|
||
|
||
3. **Semantic Search** (Feature 2)
|
||
- **Presentation**: Unified search bar (no visible keyword/semantic toggle)
|
||
- **Result Indication**: Blue badge "Semantic Match" next to relevant results
|
||
- **Visual**: Dashed blue underline for semantic match terms
|
||
- **No separation**: Users don't distinguish keyword vs semantic - "it just works"
|
||
|
||
4. **Paragraph Reformulation** (Feature 3)
|
||
- **Trigger**: Manual "✨ Reformulate" button appears on paragraph hover
|
||
- **Presentation**: Modal dialog with comparison (original | AI suggestion)
|
||
- **Interaction**: Accept/Reject/Retry options
|
||
- **Visual**: Purple border for modal, green checkmark for accepted text
|
||
|
||
5. **AI Status Badge** (Direction B Enhancement)
|
||
- **Location**: Header, right side (before user menu)
|
||
- **Content**: "✨ AI: On" with dropdown access to settings
|
||
- **Purpose**: Permanent AI visibility without occupying UI space
|
||
- **Dropdown**: Quick access to AI features status, settings, provider info
|
||
|
||
**Color Strategy (Direction A):**
|
||
- **Background**: Pure white (#FFFFFF) - content focus
|
||
- **Cards**: White with subtle gray border (#E5E7EB) + shadow-sm
|
||
- **AI Elements**: Violet (#8B5CF6) and Blue (#3B82F6) ONLY for AI interactions
|
||
- **No permanent AI zones**: No dedicated AI panel backgrounds or colored sections
|
||
|
||
**Spacing Strategy:**
|
||
- **Masonry Gap**: 16px (space-4) - comfortable breathing room
|
||
- **Card Padding**: 16px (space-4) - consistent with 8px grid
|
||
- **Sidebar Width**: 256px (w-64) - sufficient for cahier names
|
||
- **Header Height**: 64px (h-16) - compact but functional
|
||
|
||
**Typography Strategy:**
|
||
- **Cahier Titles**: 24px semibold (text-2xl font-semibold) - clear navigation
|
||
- **Note Card Titles**: 20px semibold (text-xl font-semibold) - scannable
|
||
- **Body Content**: 16px normal (text-base font-normal) - optimal readability
|
||
- **AI Text**: System fonts, purple color for AI-generated content
|
||
|
||
### Design Rationale
|
||
|
||
**Why "Invisible IA" with AI Badge?**
|
||
|
||
**1. Alignment with "Zéro Prise de Tête" Philosophy**
|
||
- Users focus on **capturing notes**, not managing AI features
|
||
- AI appears **contextually** (toasts, hover states) without cluttering the interface
|
||
- No permanent AI panel means **maximum space for content**
|
||
- Progressive discovery: Users encounter AI features **naturally** through use
|
||
|
||
**2. Optimal for Cahiers Structure**
|
||
- Masonry grid maximizes **note visibility** within each notebook
|
||
- Sidebar Cahiers + full-screen grid = **clear mental model**
|
||
- Switching notebooks shows **different note collections** instantly
|
||
- Memory Echo scoped to current Cahier = **relevant, not overwhelming** connections
|
||
|
||
**3. Creates Strong "Aha!" Emotional Response**
|
||
- Memory Echo toast appearing from "nowhere" = **surprise and delight**
|
||
- "I didn't search, it found me" = **proactive intelligence**
|
||
- No permanent AI UI means the AI feels **magical, not mechanical**
|
||
- Purple/blue accents make AI moments **visually distinctive**
|
||
|
||
**4. MVP Simplicity**
|
||
- Fewer components to build (no permanent AI panel, no mode switching)
|
||
- Focus on **4 core features** without complex UI state management
|
||
- Easier to test and iterate on **individual AI interactions**
|
||
- Faster to implement with **existing Radix UI primitives** (Toast, Dropdown, Dialog)
|
||
|
||
**5. Scalability**
|
||
- Can add AI Panel later if users request more visibility
|
||
- Badge AI provides **hook for future AI features** (chat, commands)
|
||
- Invisible IA foundation means **new features can be added** without redesign
|
||
- User behavior analytics will inform **which AI features need more visibility**
|
||
|
||
**Why the AI Badge Element?**
|
||
|
||
**From Direction B Evaluation:**
|
||
- Users need **assurance AI is working** (especially Ollama local users)
|
||
- Badge provides **quick access to AI settings** without hunting
|
||
- Dropdown menu enables **future AI feature discovery** (as features are added)
|
||
- Balances **invisibility with visibility** - AI is present but not intrusive
|
||
|
||
**Badge Placement Strategy:**
|
||
- Header right = **standard location** for status indicators
|
||
- Before user menu = **associates AI with user identity**
|
||
- Purple sparkle emoji ✨ = **clear visual marker** of AI presence
|
||
- Dropdown reveals **AI feature status** (e.g., "Memory Echo: Daily", "Provider: Ollama")
|
||
|
||
### Implementation Approach
|
||
|
||
**Phase 1: Core Layout (Week 1-2)**
|
||
|
||
1. **Sidebar (Cahiers Navigation)**
|
||
- Use existing Radix UI `NavigationMenu` or custom sidebar
|
||
- 256px width (w-64), collapsible on mobile (hamburger menu)
|
||
- Cahier items: Icon + Name + Note count badge
|
||
- Active state: Purple left border + purple text
|
||
- "Inbox" as default cahier (first item)
|
||
|
||
2. **Masonry Grid (Note Display)**
|
||
- Use existing `MasonryGrid` component from component inventory
|
||
- Responsive: 1 col (mobile) → 2 col (tablet) → 3-4 col (desktop)
|
||
- Gap: 16px (space-4)
|
||
- Note cards: White bg, border gray-200, shadow-sm, hover:shadow-md
|
||
|
||
3. **Header (Top Bar)**
|
||
- 64px height (h-16)
|
||
- Left: Logo + Cahier name (breadcrumb)
|
||
- Center: Search bar (unified keyword + semantic)
|
||
- Right: ✨ AI Badge (dropdown) + User menu
|
||
|
||
**Phase 2: AI Feature Components (Week 2-4)**
|
||
|
||
4. **Memory Echo Toast**
|
||
- Radix UI `Toast` primitive with custom styling
|
||
- Position: bottom-right, 16px from edges
|
||
- Animation: fade-in (0.2s ease-out), respects `prefers-reduced-motion`
|
||
- Purple border (2px solid #8B5CF6), white bg with purple-50 tint
|
||
- Content: 💡 icon + "I noticed something..." + connection details
|
||
- Actions: Link notes button, 👍👎 feedback, dismiss (X)
|
||
- Accessibility: `role="alert"`, `aria-live="polite"`
|
||
|
||
5. **Title Suggestions Dropdown**
|
||
- Radix UI `DropdownMenu` triggered on title focus/blur
|
||
- Content: 3 title options with ✨ prefix
|
||
- Visual: Purple text (text-purple-600), hover:bg-purple-50
|
||
- Interaction: Click to accept, ESC to close
|
||
- Trigger logic: Show after user types content, then focuses title
|
||
|
||
6. **Semantic Search Badges**
|
||
- Component: Small badge next to search results
|
||
- Content: "Semantic Match" in blue (text-blue-600)
|
||
- Position: Below note title, above content preview
|
||
- Visual: Blue border, dashed underline for matched terms
|
||
- Logic: Show when cosine similarity > 0.75
|
||
|
||
7. **Reformulation Modal**
|
||
- Radix UI `Dialog` with comparison view
|
||
- Layout: Two-column (original | AI suggestion)
|
||
- Visual: Purple border (2px), gray-50 background for comparison
|
||
- Actions: Accept (green button), Reject (gray button), Retry (purple button)
|
||
- Trigger: "✨ Reformulate" button on paragraph hover
|
||
|
||
8. **AI Badge Dropdown (Direction B Element)**
|
||
- Radix UI `DropdownMenu` in header
|
||
- Trigger: "✨ AI: On" button
|
||
- Content:
|
||
- Feature status (Memory Echo: Daily, Provider: Ollama)
|
||
- Quick settings links (Configure AI, Privacy)
|
||
- Provider indicator (Local 🏠 | Cloud ☁️)
|
||
- Visual: Purple text, hover:bg-purple-50
|
||
|
||
**Phase 3: Responsive Behavior (Week 4)**
|
||
|
||
9. **Mobile Adaptations**
|
||
- Sidebar: Hamburger menu (collapse to off-canvas)
|
||
- Masonry: Single column, full-width cards
|
||
- Memory Echo: Full-width toast at bottom
|
||
- Search: Expand on focus (compact icon → full bar)
|
||
- AI Badge: Compact on mobile (✨ icon only, tap for menu)
|
||
|
||
10. **Tablet Optimizations**
|
||
- Sidebar: 200px width or collapsible
|
||
- Masonry: 2 columns
|
||
- Memory Echo: Bottom-right toast (same as desktop)
|
||
- Touch targets: Minimum 44×44px (WCAG)
|
||
|
||
**Phase 4: Polish & Micro-interactions (Week 5)**
|
||
|
||
11. **Animations**
|
||
- Masonry: Fade-in cards (0.2s ease-out)
|
||
- Memory Echo: Slide-up fade-in (0.3s ease-out)
|
||
- Hover states: 0.15s transitions
|
||
- Respect `prefers-reduced-motion` for all animations
|
||
|
||
12. **Accessibility**
|
||
- Focus indicators: 2px purple outline
|
||
- Keyboard navigation: Tab through all interactive elements
|
||
- Screen reader: ARIA labels for AI components
|
||
- Color contrast: 4.5:1 minimum (WCAG AA)
|
||
|
||
13. **Loading States**
|
||
- AI processing: Amber spinner (#F59E0B) with "AI thinking..." text
|
||
- Semantic search: Skeleton cards while computing embeddings
|
||
- Provider status: Green check (Ollama running) or red X (offline)
|
||
|
||
**Component Timeline Summary:**
|
||
|
||
| Component | Radix Primitive | Week | Priority |
|
||
|-----------|-----------------|------|----------|
|
||
| Sidebar Cahiers | NavigationMenu | 1 | P0 |
|
||
| Masonry Grid | Custom (existing) | 1 | P0 |
|
||
| Header | Flex layout | 1 | P0 |
|
||
| AI Badge Dropdown | DropdownMenu | 1 | P0 |
|
||
| Memory Echo Toast | Toast | 2 | P0 (Defining) |
|
||
| Title Suggestions | DropdownMenu | 2 | P1 |
|
||
| Semantic Search Badge | Custom | 3 | P1 |
|
||
| Reformulation Modal | Dialog | 3 | P1 |
|
||
| Mobile Responsive | Media queries | 4 | P1 |
|
||
|
||
**Design Tokens Implementation (Tailwind Config):**
|
||
|
||
```javascript
|
||
// tailwind.config.js extension
|
||
module.exports = {
|
||
theme: {
|
||
extend: {
|
||
colors: {
|
||
ai: {
|
||
primary: '#8B5CF6', // Violet
|
||
accent: '#3B82F6', // Blue
|
||
success: '#10B981', // Green
|
||
warning: '#F59E0B', // Amber
|
||
light: '#F5F3FF', // Purple-50
|
||
}
|
||
},
|
||
spacing: {
|
||
'18': '4.5rem', // 72px - card gap large
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
**Success Criteria for Direction A:**
|
||
|
||
✅ **Masonry grid fills ≥70% of viewport** (content-first metric)
|
||
✅ **AI features appear in ≤200ms** (responsive feel)
|
||
✅ **Memory Echo creates "Aha!" moment** (user testing)
|
||
✅ **Users discover ≥2 AI features organically** (no tutorial needed)
|
||
✅ **Cahier switching takes ≤100ms** (instant mental model)
|
||
✅ **Mobile single-column works without horizontal scroll** (responsive)
|
||
✅ **WCAG AA compliance** (accessibility)
|
||
|
||
**What This Direction Avoids (from other directions):**
|
||
|
||
❌ No permanent AI panel (Direction B) - maximizes content space
|
||
❌ No mode switching (Direction C) - reduces cognitive load
|
||
❌ No colored background zones - maintains clean white aesthetic
|
||
❌ No complex transitions - faster to implement, less to go wrong
|
||
|
||
---
|
||
|
||
## User Journey Flows
|
||
|
||
### Journey 1: Fast Capture avec Cahiers & Title Suggestions
|
||
|
||
**Persona:** Alex - Creative Developer qui veut capturer vite
|
||
|
||
**Parcours:** Capturer une idée dans un Cahier → Recevoir suggestions de titres → Accepter/refuser
|
||
|
||
**Flow Diagram:**
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([Alex ouvre Memento]) --> SelectCahier{Sélectionne Cahier}
|
||
SelectCahier -->|Inbox par défaut| ViewGrid[Voir grille masonry Inbox]
|
||
SelectCahier -->|Cahier existant| ViewGrid
|
||
SelectCahier -->|Nouveau Cahier| CreateCahier[Créer nouveau Cahier]
|
||
CreateCahier --> ViewGrid
|
||
|
||
ViewGrid --> ClickNew[Click '+ New Note']
|
||
ClickNew --> NoteEditor[Note Editor: Focus sur contenu]
|
||
NoteEditor --> TypeContent[Alex tape frénétiquement<br/>50+ mots en 2min]
|
||
|
||
TypeContent --> CheckTitle{Titre présent?}
|
||
CheckTitle -->|Oui| SaveNote[Sauvegarder note]
|
||
CheckTitle -->|Non| TriggerAI[AI Trigger: 50+ mots sans titre]
|
||
|
||
TriggerAI --> ShowToast[🔔 Toast subtil:<br/>💭 '3 idées de titres?']
|
||
ShowToast --> UserDecision{Action Alex?}
|
||
|
||
UserDecision -->|Ignore Continue| AutoDismiss[Auto-dismiss 30s]
|
||
UserDecision -->|Click 'Voir'| ShowDropdown[Dropdown avec 3 titres<br/>✨ Titre 1<br/>✨ Titre 2<br/>✨ Titre 3]
|
||
UserDecision -->|Click 'Ne plus demander'| DismissPerm[Dismiss pour cette note]
|
||
|
||
ShowDropdown --> SelectTitle{Alex choisit?}
|
||
SelectTitle -->|Click Titre 1| ApplyTitle1[Appliquer Titre 1]
|
||
SelectTitle -->|Click Titre 2| ApplyTitle2[Appliquer Titre 2]
|
||
SelectTitle -->|Click Titre 3| ApplyTitle3[Appliquer Titre 3]
|
||
SelectTitle -->|ESC/Click outside| DismissDropdown[Fermer dropdown]
|
||
|
||
ApplyTitle1 --> SaveNote
|
||
ApplyTitle2 --> SaveNote
|
||
ApplyTitle3 --> SaveNote
|
||
DismissDropdown --> ManualTitle[Alex tape titre manuel]
|
||
DismissPerm --> ManualTitle
|
||
AutoDismiss --> ManualTitle
|
||
|
||
ManualTitle --> SaveNote
|
||
SaveNote --> ShowInCard[Note apparaît dans masonry<br/>avec titre appliqué]
|
||
ShowInCard --> EmbedAsync[Background: Générer embedding<br/>pour semantic search]
|
||
EmbedAsync --> End([Fin: Note capturée])
|
||
|
||
style TriggerAI fill:#8B5CF6,color:#fff
|
||
style ShowToast fill:#F5F3FF
|
||
style ShowDropdown fill:#8B5CF6,color:#fff
|
||
style EmbedAsync fill:#3B82F6,color:#fff
|
||
```
|
||
|
||
**Optimizations "Zéro Prise de Tête":**
|
||
- ✅ **No interruption:** Toast appears without blocking typing
|
||
- ✅ **Default value:** Inbox = default Cahier for ultra-fast capture
|
||
- ✅ **Respect choice:** "Don't ask again" = immediate, no confirmation
|
||
- ✅ **Background processing:** Embedding generated without blocking UI
|
||
|
||
**Moments of Delight:**
|
||
- 💜 **Positive surprise:** "Wow, the first one captures exactly the essence!"
|
||
- ⚡ **Performance:** Instant dropdown (< 200ms)
|
||
|
||
---
|
||
|
||
### Journey 2: Semantic Search Discovery
|
||
|
||
**Persona:** Alex - Cherche une note mais se souvient du sens, pas des mots
|
||
|
||
**Parcours:** Rechercher avec intention naturelle → Voir résultats sémantiques → Découvrir la bonne note
|
||
|
||
**Flow Diagram:**
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([Alex veut retrouver<br/>sa note React]) --> ClickSearch[Click barre de recherche<br/>header center]
|
||
ClickSearch --> SearchExpand[Search bar s'agrandit<br/>placeholder: 'Rechercher...']
|
||
SearchExpand --> TypeQuery[Alex tape naturellement:<br/>'comment optimiser les performances des hooks']
|
||
|
||
TypeQuery --> Debounce[Debounce 300ms]
|
||
Debounce --> SearchHybrid[Hybrid Search:<br/>1. Keyword Search<br/>2. Semantic Search]
|
||
|
||
SearchHybrid --> KeywordResults[Keyword Search:<br/>Résultats avec mots exacts]
|
||
SearchHybrid --> SemanticResults[Semantic Search:<br/>Vector embeddings]
|
||
|
||
KeywordResults --> CombineResults[Combiner & Ranker]
|
||
SemanticResults --> SimilarityThreshold{Cosine Similarity<br/>> 0.75?}
|
||
|
||
SimilarityThreshold -->|Oui| AddSemantic[Ajouter badge 'Semantic Match'<br/>Score: 0.82]
|
||
SimilarityThreshold -->|Non| KeywordOnly[Résultats keyword uniquement]
|
||
|
||
AddSemantic --> CombineResults
|
||
KeywordOnly --> CombineResults
|
||
|
||
CombineResults --> ShowResults[Afficher 10 résultats<br/>masonry style]
|
||
ShowResults --> ResultBadges[Badges sur résultats:<br/>🎯 Correspondance exacte<br/>🎯 Correspondance sémantique]
|
||
|
||
ResultBadges --> AlexScans[Alex scanne les résultats]
|
||
AlexScans --> TopResult[1er résultat:<br/>Titre: 'React State Management'<br/>Badge: 🎯 Correspondance sémantique<br/>Score: 0.82]
|
||
|
||
TopResult --> AlexRealize{Alex réalise}
|
||
AlexRealize -->|Wow!| NoteNoKeywords[Note ne contient PAS<br/>'hook' ou 'performance']
|
||
AlexRealize -->|Click| OpenNote[Ouvrir la note]
|
||
|
||
NoteNoKeywords --> ConceptMatch[IA a compris le CONCEPT,<br/>pas juste les mots-clés]
|
||
ConceptMatch --> AhaMoment[Alex: 'C'est exactement<br/>ce que je cherchais!']
|
||
|
||
OpenNote --> NoteFull[Alex voit note complète:<br/>Content parle de useMemo<br/>pour optimiser les performances]
|
||
NoteFull --> Success([Succès: Note retrouvée])
|
||
|
||
AhaMoment --> Success
|
||
|
||
style SearchHybrid fill:#3B82F6,color:#fff
|
||
style SemanticResults fill:#8B5CF6,color:#fff
|
||
style AddSemantic fill:#3B82F6,color:#fff
|
||
style AhaMoment fill:#10B981,color:#fff
|
||
```
|
||
|
||
**Optimizations "Zéro Prise de Tête":**
|
||
- ✅ **Unified search:** No visible keyword/semantic toggle - "it just works"
|
||
- ✅ **Explicit badges:** User understands WHY this result appears
|
||
- ✅ **Confidence score:** Cosine similarity > 0.75 = false positive filtering
|
||
|
||
**Moments of Delight:**
|
||
- 🎯 **Intention understood:** "It understood what I meant, not what I typed!"
|
||
- ⚡ **Instant:** Results < 500ms
|
||
|
||
---
|
||
|
||
### Journey 3: Memory Echo "Aha!" Moment
|
||
|
||
**Persona:** Alex/Max - Découverte proactive de connexions invisibles
|
||
|
||
**Parcours:** Recevoir notification inattendue → Voir connexion → Feedback 👍👎
|
||
|
||
**Flow Diagram:**
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([Alex utilise Memento<br/>normalement]) --> BackgroundProcess[Background Daily:<br/>Analyser embeddings<br/>du Cahier actuel]
|
||
|
||
BackgroundProcess --> FindSimilar{Cosine Similarity<br/>> 0.75 entre notes?}
|
||
FindSimilar -->|Non| NoInsight[Pas d'insight aujourd'hui]
|
||
FindSimilar -->|Oui| TimeFilter{Notes de<br/>périodes différentes?}
|
||
|
||
TimeFilter -->|Non| NoInsight
|
||
TimeFilter -->|Oui| CheckFrequency{Frequency setting<br/>OK? (max 1/jour)}
|
||
|
||
CheckFrequency -->|Non| NoInsight
|
||
CheckFrequency -->|Oui| CheckLastShown{Déjà montré<br/>cette connexion?}
|
||
|
||
CheckLastShown -->|Oui| NoInsight
|
||
CheckLastShown -->|Non| PrepareEcho[Préparer Memory Echo]
|
||
|
||
PrepareEcho --> GetNoteA[Récupérer Note A:<br/>'Node.js performance tips']
|
||
PrepareEcho --> GetNoteB[Récupérer Note B:<br/>'Next.js optimization']
|
||
PrepareEcho --> Connection[Connexion identifiée:<br/>Server-side rendering optimization]
|
||
|
||
GetNoteA --> ShowToast
|
||
GetNoteB --> ShowToast
|
||
Connection --> ShowToast
|
||
|
||
ShowToast[💡 Toast Notification:<br/>'J'ai remarqué quelque chose<br/>dans tes notes Work...']
|
||
ShowToast --> AlexReaction{Réaction d'Alex?}
|
||
|
||
AlexReaction -->|Ignore/Dismiss| AutoDismiss[Auto-dismiss 30s]
|
||
AlexReaction -->|Click 'Voir la connexion'| ShowModal[Modal Memory Echo Card]
|
||
|
||
ShowModal[Modal: 2 notes côte à côte<br/>Note A | Note B<br/>'Toutes deux traitent de<br/>server-side rendering optimization']
|
||
ShowModal --> AlexReads[Alex lit les deux notes]
|
||
AlexReads --> AlexRealizes{Alex réalise la connexion}
|
||
|
||
AlexRealizes -->|Wow!| ClickLink[Click 'Lier les notes']
|
||
AlexRealizes -->|Faux| ClickReject[Click 👎 'Faux']
|
||
|
||
ClickLink --> ApplyTag[Ajouter tag commun<br/>'SSR optimization']
|
||
ApplyTag --> ShowSuccess[✅ Notes liées!]
|
||
ShowSuccess --> FeedbackPrompt[Prompt feedback:<br/>👍 'Clever!' | 👎 'Faux']
|
||
|
||
ClickReject --> FeedbackModal[Modal:<br/>'Pourquoi pas pertinent?']
|
||
FeedbackModal --> UserExplanation[Alex explique:<br//'Pas de rapport']
|
||
UserExplanation --> LearnSystem[Système apprend:<br/>Réduire poids similarité]
|
||
|
||
FeedbackPrompt --> FeedbackChoice{Alex choisit?}
|
||
FeedbackChoice -->|👍| LearnGood[Apprendre:<br/>Augmenter poids ce type connexion]
|
||
FeedbackChoice -->|👎| LearnBad[Apprendre:<br/>Réduire poids]
|
||
FeedbackChoice -->|Skip| NoLearn
|
||
|
||
LearnGood --> End([Fin: Insight mémorisé])
|
||
LearnBad --> End
|
||
LearnSystem --> End
|
||
NoLearn --> End
|
||
AutoDismiss --> End
|
||
NoInsight --> End([Fin: Pas d'insight])
|
||
|
||
style BackgroundProcess fill:#3B82F6,color:#fff
|
||
style ShowToast fill:#8B5CF6,color:#fff
|
||
style ShowModal fill:#F5F3FF
|
||
style ClickLink fill:#10B981,color:#fff
|
||
style LearnGood fill:#10B981,color:#fff
|
||
style LearnBad fill:#EF4444,color:#fff
|
||
```
|
||
|
||
**Optimizations "Zéro Prise de Tête":**
|
||
- ✅ **Non-intrusive:** Max 1 insight/day, no overwhelm
|
||
- ✅ **Cahier scope:** Analysis only in current Cahier (relevant connections)
|
||
- ✅ **Immediate feedback:** 👍👎 trains the system, no confirmation
|
||
- ✅ **Global toggle:** Option for cross-Cahier connections
|
||
|
||
**"Aha!" Moment:**
|
||
- 💡 **Surprise & Discovery:** "I never made the connection!"
|
||
- 🎯 **Serendipity:** "I didn't search, it found me!"
|
||
|
||
---
|
||
|
||
### Journey 4: AI Error Recovery & Control
|
||
|
||
**Persona:** Sophie - L'IA se trompe, elle ajuste les settings
|
||
|
||
**Parcours:** Recevoir mauvaise suggestion → Feedback négatif → Ajuster settings → Retrouver la confiance
|
||
|
||
**Flow Diagram:**
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start([Sophie crée une note]) --> WriteContent[Sophie écrit 70 mots<br/>sur stratégie contenu]
|
||
WriteContent --> TriggerAI[AI Trigger:<br/>Title Suggestions]
|
||
TriggerAI --> ShowSuggestions[Affiche 3 titres:<br/>1. 'Stratégie B2B'<br/>2. 'Marketing 2025'<br/>3. 'Idées Articles']
|
||
|
||
ShowSuggestions --> SophieReaction{Sophie réagit}
|
||
SophieReaction -->|Déçue| ClickDismiss[Click 'Ne plus demander']
|
||
SophieReaction -->|Choisit| SelectTitle[Sélectionne titre]
|
||
|
||
ClickDismiss --> DismissNote[Toast: 'Pas de soucis,<br/>je ne te redemanderai pas<br/>pour cette note']
|
||
DismissNote --> SophieManual[Sophie tape titre manuel]
|
||
SophieManual --> SaveNote[Sauvegarder]
|
||
|
||
SaveNote --> NextDay[Jour suivant:]
|
||
NextDay --> MemoryEcho[Memory Echo:<br/>Recettes smoothies + SEO]
|
||
MemoryEcho --> SophieConfused{Sophie confuse}
|
||
|
||
SophieConfused -->|Pas de rapport!| ClickThumbsDown[Click 👎 'Faux']
|
||
ClickThumbsDown --> FeedbackModal[Modal:<br/>'Pourquoi pas pertinent?']
|
||
|
||
FeedbackModal --> SophieExplains[Sophie explique:<br/>'Smoothies = personnel<br/>SEO = pro']
|
||
SophieExplains --> SystemLearn[Système apprend:<br/>Contexte personnel vs pro]
|
||
SystemLearn --> DismissToast[Toast: 'Merci!<br/>Je ferai mieux next time']
|
||
|
||
DismissToast --> SophieSettings[Sophie va dans Settings > AI]
|
||
SophieSettings --> SeeCurrent[Voit settings actuels:<br/>☑ Title Suggestions: 50+ mots<br/>☑ Memory Echo: Max 1/jour]
|
||
|
||
SeeCurrent --> SophieAdjusts{Sophie ajuste}
|
||
SophieAdjusts -->|Title Suggestions| AdjustTitle[Ajuster:<br/>'Me demander seulement<br/>si > 100 mots']
|
||
SophieAdjusts -->|Memory Echo| AdjustEcho[Ajuster:<br/>'Seulement notes des<br/>30 derniers jours']
|
||
SophieAdjusts -->|Language| AdjustLang[Forcer langue = FR<br/>pour éviter titres EN]
|
||
|
||
AdjustTitle --> SaveSettings[Sauvegarder settings]
|
||
AdjustEcho --> SaveSettings
|
||
AdjustLang --> SaveSettings
|
||
|
||
SaveSettings --> WeekLater[Une semaine plus tard:]
|
||
WeekLater --> NewNote[Sophie écrit 200 mots]
|
||
NewNote --> BetterSuggestions[Meilleures suggestions:<br/>1. 'Content Marketing: Comment créer...'<br/>2. 'Guide Marketing: De la stratégie...'<br/>3. 'Stratégie: Les 5 piliers B2B']
|
||
|
||
BetterSuggestions --> SophieHappy[Sophie: 'Number 3 is perfect!']
|
||
SophieHappy --> ApplyTitre3[Appliquer Titre 3]
|
||
ApplyTitre3 --> TrustRestored[Confiance restaurée!]
|
||
|
||
TrustRestored --> MemoryEcho2[Memory Echo:<br/>Deux notes marketing<br/>30 derniers jours]
|
||
MemoryEcho2 --> SophieClickThumbsUp[Sophie clique 👍]
|
||
SophieClickThumbsUp --> LearnPositive[Système apprend:<br/>Connexions pertinentes]
|
||
|
||
LearnPositive --> Success([Fin: Sophie personnalisé<br/>son expérience IA])
|
||
|
||
style ClickDismiss fill:#F59E0B
|
||
style ClickThumbsDown fill:#EF4444,color:#fff
|
||
style FeedbackModal fill:#FEE2E2
|
||
style SophieSettings fill:#3B82F6,color:#fff
|
||
style SophieHappy fill:#10B981,color:#fff
|
||
style TrustRestored fill:#10B981,color:#fff
|
||
style Success fill:#10B981,color:#fff
|
||
```
|
||
|
||
**Optimizations "Zéro Prise de Tête":**
|
||
- ✅ **Granular control:** Each feature has independent settings
|
||
- ✅ **Immediate respect:** "Don't ask again" = no confirmation
|
||
- ✅ **Explanatory feedback:** Modal explains why system is asking
|
||
- ✅ **Learning curve:** System improves over time
|
||
|
||
**Trust Recovery:**
|
||
- 🔄 **User control:** Sophie can customize EVERYTHING
|
||
- 📈 **Progression:** 55% acceptance → trust restored
|
||
|
||
---
|
||
|
||
### Journey Patterns
|
||
|
||
Based on the 4 flows above, here are the **reusable patterns**:
|
||
|
||
#### Navigation Patterns
|
||
|
||
**Pattern 1: Cahier-First Navigation**
|
||
- **Entry:** Always in a Cahier (Inbox default)
|
||
- **Switching:** Click Cahier in sidebar → instant switch (< 100ms)
|
||
- **Breadcrumb:** Header shows "Memento > Work > [Current note]"
|
||
- **Mental Model:** 1 Cahier = 1 work context
|
||
|
||
**Pattern 2: Contextual AI Appearance**
|
||
- **Principle:** AI appears at the right moment, not before
|
||
- **Triggers:** Titles (50+ words), Memory Echo (daily), Reformulation (hover)
|
||
- **Dismiss:** One-click dismiss, immediate respect
|
||
- **Reappear:** Only if criteria met again
|
||
|
||
#### Decision Patterns
|
||
|
||
**Pattern 1: Progressive Disclosure**
|
||
- **Show:** Information revealed progressively
|
||
- **Dropdown:** 3 options (not more, reduced overwhelm)
|
||
- **Modal:** For complex decisions (Memory Echo)
|
||
- **Inline:** For simple feedback (👍👎)
|
||
|
||
**Pattern 2: Default + Override**
|
||
- **Default:** Inbox Cahier for fast capture
|
||
- **Override:** User can choose different Cahier
|
||
- **AI Settings:** Team defaults + user overrides
|
||
- **Frequency:** Max limits, user can lower
|
||
|
||
#### Feedback Patterns
|
||
|
||
**Pattern 1: Triple Coding Feedback**
|
||
- **Visual:** Color (purple/blue for AI)
|
||
- **Icon:** 💡 for Memory Echo, ✨ for suggestions
|
||
- **Text:** Explicit labels ("Correspondance sémantique")
|
||
|
||
**Pattern 2: Learning Loop**
|
||
- **User Action:** 👍 or 👎
|
||
- **System Response:** "Thanks!" toast
|
||
- **Explanation:** Modal explains why (if 👎)
|
||
- **Adaptation:** Next suggestions improved
|
||
|
||
---
|
||
|
||
### Flow Optimization Principles
|
||
|
||
**1. Minimize Steps to Value**
|
||
- **Fast Capture:** Inbox → Type → Save (3 steps)
|
||
- **Semantic Search:** Type → Results (no extra clicks)
|
||
- **Cahier switching:** 1 click = instant switch
|
||
|
||
**2. Reduce Cognitive Load**
|
||
- **Unified Search:** No keyword/semantic choice
|
||
- **Cahier Context:** Memory Echo scoped = relevant connections
|
||
- **Smart Defaults:** Inbox = default, no thinking required
|
||
|
||
**3. Clear Feedback & Progress**
|
||
- **Toast Notifications:** "💡 I noticed something..."
|
||
- **Badges:** "🎯 Semantic Match" with score
|
||
- **Loading States:** Spinner + "AI thinking..." text
|
||
|
||
**4. Moments of Delight**
|
||
- **Title Suggestions:** "Wow, the first one captures exactly the essence!"
|
||
- **Semantic Search:** "It understood what I meant, not what I typed!"
|
||
- **Memory Echo:** "I never made the connection!"
|
||
|
||
**5. Graceful Error Recovery**
|
||
- **"Don't ask again":** Immediate dismiss, no confirmation
|
||
- **👎 Feedback:** Explanatory modal for learning
|
||
- **Settings Access:** Quick access via AI Badge dropdown
|
||
|
||
---
|
||
|
||
## Component Strategy
|
||
|
||
### Design System Components
|
||
|
||
**Available from Radix UI:**
|
||
|
||
Memento's chosen design system (Radix UI + Tailwind CSS) provides comprehensive primitive components:
|
||
|
||
- ✅ **Dialog** - Modal overlays (Reformulation comparison)
|
||
- ✅ **Dropdown Menu** - Menus and dropdowns (Title suggestions, AI Badge)
|
||
- ✅ **Toast** - Temporary notifications (Memory Echo base)
|
||
- ✅ **Switch** - Toggle controls (AI settings ON/OFF)
|
||
- ✅ **Navigation Menu** - Sidebar navigation (Cahiers)
|
||
- ✅ **Scroll Area** - Scrollable containers (Masonry grid)
|
||
- ✅ **Tooltip** - Help text and icon explanations
|
||
- ✅ **Separator** - Visual dividers and borders
|
||
|
||
**Available from Component Inventory (Existing Memento):**
|
||
|
||
Based on component inventory analysis, these components are already built:
|
||
|
||
- ✅ **NoteCard** - Note cards in masonry grid
|
||
- ✅ **MasonryGrid** - Responsive masonry layout
|
||
- ✅ **Header** - Top bar with logo, search, user menu
|
||
- ✅ **Sidebar** - Side navigation (adapt for Cahiers)
|
||
- ✅ **LabelSelector** - Tag selection component
|
||
- ✅ **NoteEditor** - Rich text note editor
|
||
- ✅ **LoginForm** - Authentication UI
|
||
|
||
**Gap Analysis:**
|
||
|
||
AI features require **7 custom components** not available in Radix UI or existing inventory:
|
||
|
||
1. ❌ **MemoryEchoCard** - Specialized toast with 2 notes side-by-side
|
||
2. ❌ **SemanticSearchBadge** - "Semantic Match" badge with confidence score
|
||
3. ❌ **TitleSuggestionsDropdown** - Dropdown with 3 AI-generated titles
|
||
4. ❌ **ReformulationModal** - Comparison modal (original | AI suggestion)
|
||
5. ❌ **ProviderIndicator** - AI provider status (Local/Cloud + connection)
|
||
6. ❌ **AIToast** - AI-styled toast with purple border
|
||
7. ❌ **ProcessingIndicator** - "AI thinking..." spinner with text
|
||
|
||
---
|
||
|
||
### Custom Components
|
||
|
||
#### Component 1: MemoryEchoCard
|
||
|
||
**Purpose:** Proactively display a connection between 2 notes (defining "Aha!" experience)
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌─────────────────────────────────────────────────┐
|
||
│ 💡 I noticed something in your **Work** notes... │
|
||
├─────────────────────┬───────────────────────────┤
|
||
│ Note A │ Note B │
|
||
│ "Node.js tips" │ "Next.js optimization" │
|
||
│ Preview: 50 chars │ Preview: 50 chars │
|
||
├─────────────────────┴───────────────────────────┤
|
||
│ Connection: Server-side rendering optimization │
|
||
│ [Dismiss] [View] │
|
||
└─────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Appears as toast notification (bottom-right, 16px from edges)
|
||
- Shows 2 notes with semantic similarity > 0.75
|
||
- Displays connection explanation (AI-generated context)
|
||
|
||
**States:**
|
||
- **Appearing:** Fade-in slide-up (0.3s ease-out)
|
||
- **Visible:** Subtle border pulse (purple)
|
||
- **Hover:** Shadow increase (shadow-lg), solid border
|
||
- **Dismissed:** Fade-out slide-down (0.2s)
|
||
|
||
**Accessibility:**
|
||
- `role="alert"` - Important notification
|
||
- `aria-live="polite"` - Non-interruptive
|
||
- `aria-label="AI notification: Note connection discovered"`
|
||
- Keyboard: ESC to dismiss, Tab to "View Connection" button
|
||
|
||
**Content Guidelines:**
|
||
- Headline: "💡 I noticed something in your **[Cahier name]** notes..."
|
||
- Connection: 1-2 sentence explanation of semantic link
|
||
- Note previews: 50 characters max, truncation with "..."
|
||
|
||
**Interaction Behavior:**
|
||
- Auto-dismiss after 30 seconds
|
||
- Dismissible with X button (top-right)
|
||
- "View Connection" → Opens link notes action or modal
|
||
- 👍👎 feedback buttons after viewing
|
||
|
||
**Design Tokens:**
|
||
- Border: `2px solid var(--ai-connection)` (#8B5CF6)
|
||
- Background: `var(--background)` (#FFFFFF) with `var(--ai-light)` tint (#F5F3FF)
|
||
- Shadow: `shadow-lg` on hover
|
||
- Corner radius: `rounded-xl` (12px)
|
||
|
||
---
|
||
|
||
#### Component 2: SemanticSearchBadge
|
||
|
||
**Purpose:** Indicate that a search result is a semantic match (not keyword match)
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌─────────────────────────────────────┐
|
||
│ Note Title: "React State..." │
|
||
│ 🎯 Semantic Match (Score: 0.82) │ ← Badge here
|
||
│ Content preview... │
|
||
└─────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Appears below note title in search results
|
||
- Only shows when cosine similarity > 0.75
|
||
- Indicates semantic understanding vs exact keyword match
|
||
|
||
**States:**
|
||
- **Default:** Blue background (bg-blue-50), blue text (text-blue-600)
|
||
- **Hover:** Blue-100 background, underline
|
||
- **Focus:** 2px blue outline (focus-visible)
|
||
|
||
**Accessibility:**
|
||
- `aria-label="Semantic match with 82% confidence"`
|
||
- Screen reader: "Semantic Match, 82 percent confidence"
|
||
|
||
**Content Guidelines:**
|
||
- Text: "🎯 Semantic Match (Score: X.XX)"
|
||
- Score format: 2 decimal places (0.82, not 0.823456)
|
||
- Tooltip on hover: "This result matches the meaning, not exact words"
|
||
|
||
**Variants:**
|
||
- **Exact Match:** No badge (default keyword search result)
|
||
- **Semantic Match:** Blue badge with score
|
||
|
||
---
|
||
|
||
#### Component 3: TitleSuggestionsDropdown
|
||
|
||
**Purpose:** Display 3 AI-generated title suggestions
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌──────────────────────────────────────┐
|
||
│ ✨ 3 Title Suggestions │
|
||
├──────────────────────────────────────┤
|
||
│ ✨ React State Management: useMemo... │ ← Hover state
|
||
│ ✨ Performance Hook Pattern pour... │
|
||
│ ✨ Astuce React: mémoisation avec... │
|
||
└──────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Triggered when user types 50+ words without title
|
||
- Appears below title field in note editor
|
||
- Shows 3 AI-generated title options
|
||
|
||
**States:**
|
||
- **Closed:** Hidden
|
||
- **Opening:** Fade-in (0.2s ease-out)
|
||
- **Open:** List visible, items hoverable
|
||
- **ItemSelected:** Green checkmark, background green-50
|
||
|
||
**Accessibility:**
|
||
- `role="listbox"` - Selectable list
|
||
- `aria-label="AI-generated title suggestions"`
|
||
- Keyboard: ↑↓ to navigate, Enter to select, ESC to close
|
||
|
||
**Content Guidelines:**
|
||
- Icon: ✨ (sparkle) for each suggestion
|
||
- Max 3 items (no scroll)
|
||
- Title length: 60-80 characters optimal
|
||
- Truncate long titles with "..."
|
||
|
||
**Interaction Behavior:**
|
||
- Trigger: 50+ words without title, focus on title field
|
||
- Position: Below title field (DropdownMenu positioning)
|
||
- Selection: Click to apply, replaces empty title
|
||
- ESC or click outside: Dismiss (user can type manual title)
|
||
|
||
**Design Tokens:**
|
||
- Item text: `text-purple-600` (AI suggestion color)
|
||
- Item hover: `hover:bg-purple-50`
|
||
- Selected: `bg-green-50` with ✓ checkmark
|
||
|
||
---
|
||
|
||
#### Component 4: ReformulationModal
|
||
|
||
**Purpose:** Compare original text with AI reformulation side-by-side
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌────────────────────────────────────────────────────┐
|
||
│ ✨ Reformulate this Paragraph │
|
||
├──────────────────────┬─────────────────────────────┤
|
||
│ Original │ AI Suggestion │
|
||
│ "This is bad text" │ "This text needs improve..." │
|
||
│ │ │
|
||
│ [Keep Original] │ [Apply Suggestion] │
|
||
├──────────────────────┴─────────────────────────────┤
|
||
│ [Retry] [Cancel] │
|
||
└────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Triggered by "✨ Reformulate" button on paragraph hover
|
||
- Shows original text vs AI reformulation
|
||
- User chooses to keep or replace
|
||
|
||
**States:**
|
||
- **Opening:** Fade-in scale (0.2s)
|
||
- **Comparing:** Two-column view, 50% width each
|
||
- **Applied:** Green checkmark, modal closes (0.1s)
|
||
- **Cancelled:** Fade-out (0.1s)
|
||
|
||
**Accessibility:**
|
||
- `role="dialog"` - Interactive modal
|
||
- `aria-labelledby="reformulation-modal-title"`
|
||
- `aria-describedby="reformulation-modal-desc"`
|
||
- Focus trap within modal
|
||
- ESC to close
|
||
|
||
**Content Guidelines:**
|
||
- Header: "✨ Reformulate this Paragraph"
|
||
- Left column: "Original" (gray-500 label)
|
||
- Right column: "AI Suggestion" (purple-600 label)
|
||
- Buttons: "Keep Original" (gray), "Apply" (green), "Retry" (purple)
|
||
|
||
**Interaction Behavior:**
|
||
- Trigger: Hover paragraph → "✨ Reformulate" button appears (top-right)
|
||
- Apply: Replaces paragraph text, green checkmark (0.5s), modal closes
|
||
- Keep: Returns to original text, modal closes
|
||
- Retry: Generates new suggestion (show ProcessingIndicator)
|
||
|
||
**Design Tokens:**
|
||
- Modal border: `2px solid var(--ai-primary)` (#8B5CF6)
|
||
- Background: `var(--surface-elevated)` (#FFFFFF)
|
||
- Button primary (Apply): `bg-green-600 hover:bg-green-700`
|
||
|
||
---
|
||
|
||
#### Component 5: ProviderIndicator
|
||
|
||
**Purpose:** Indicate AI provider status (Local Ollama / Cloud OpenAI / Custom)
|
||
|
||
**Anatomy:**
|
||
```
|
||
In AI Badge Dropdown:
|
||
┌────────────────────────────────────┐
|
||
│ AI Status │
|
||
│ 🏠 Local (Ollama) │ ← Indicator
|
||
│ ✅ Connected: localhost:11434 │
|
||
└────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Displayed in AI Badge dropdown menu
|
||
- Shows current provider and connection status
|
||
- Critical for user trust (Max's privacy journey)
|
||
|
||
**States:**
|
||
- **Local:** 🏠 icon + "Local (Ollama)"
|
||
- **Cloud:** ☁️ icon + "Cloud (OpenAI)"
|
||
- **Custom:** ⚙️ icon + "Custom (OpenAI-compatible)"
|
||
- **Connected:** ✅ green + URL/host
|
||
- **Disconnected:** ❌ red + "Not available"
|
||
- **Loading:** 🔄 spinner + "Connecting..."
|
||
|
||
**Accessibility:**
|
||
- `aria-label="AI provider status: Local Ollama, Connected"`
|
||
- Screen reader: "AI provider: Local Ollama, Connected to localhost port 11434"
|
||
|
||
**Content Guidelines:**
|
||
- Local: "🏠 Local (Ollama)"
|
||
- Cloud: "☁️ Cloud (OpenAI)"
|
||
- Custom: "⚙️ Custom (OpenAI-compatible)"
|
||
- Status: "✅ Connected: [URL]" or "❌ Disconnected"
|
||
|
||
**Variants:**
|
||
- **Compact:** Icon only (for mobile)
|
||
- **Full:** Icon + label + status (desktop)
|
||
|
||
---
|
||
|
||
#### Component 6: AIToast
|
||
|
||
**Purpose:** Custom toast for AI notifications (Memory Echo, suggestions, feedback)
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌──────────────────────────────────────────┐
|
||
│ 💡 I noticed something... [X] │
|
||
│ │
|
||
│ Connection details... │
|
||
│ [View Connection] [Dismiss] │
|
||
└──────────────────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Base component for all AI notifications
|
||
- Extends Radix UI Toast with AI-specific styling
|
||
- Used by MemoryEchoCard, TitleSuggestions, etc.
|
||
|
||
**States:**
|
||
- **Entering:** Slide-up fade-in (0.3s ease-out)
|
||
- **Visible:** Purple border (2px solid #8B5CF6)
|
||
- **Hover:** Shadow-lg, border 3px
|
||
- **Exiting:** Slide-down fade-out (0.2s)
|
||
|
||
**Accessibility:**
|
||
- `role="alert"` - Important notification
|
||
- `aria-live="polite"` - Non-interruptive
|
||
- `aria-label="AI notification"`
|
||
- Auto-dismiss respects `prefers-reduced-motion`
|
||
|
||
**Design Tokens:**
|
||
- Border: `2px solid var(--ai-connection)` (#8B5CF6)
|
||
- Background: `var(--background)` (#FFFFFF) with `var(--ai-light)` tint (#F5F3FF)
|
||
- Shadow: `shadow-lg` on hover
|
||
- Corner radius: `rounded-xl` (12px)
|
||
- Padding: `space-4` (16px) all around
|
||
|
||
**Interaction Behavior:**
|
||
- Position: Bottom-right, 16px from edges (desktop)
|
||
- Position: Bottom-center, full-width on mobile
|
||
- Auto-dismiss: Configurable (10-60s default 30s)
|
||
- Dismissible: X button (top-right) or ESC key
|
||
|
||
---
|
||
|
||
#### Component 7: ProcessingIndicator
|
||
|
||
**Purpose:** Indicate that AI is processing a request
|
||
|
||
**Anatomy:**
|
||
```
|
||
┌────────────────────────────┐
|
||
│ [Spinner] AI thinking... │
|
||
│ Generating embeddings │
|
||
└────────────────────────────┘
|
||
```
|
||
|
||
**Usage:**
|
||
- Shows during AI operations (embedding generation, reformulation)
|
||
- Provides feedback during long-running operations (> 500ms)
|
||
|
||
**States:**
|
||
- **Idle:** Hidden
|
||
- **Processing:** Amber spinner + "AI thinking..." text
|
||
- **Success:** Green checkmark (0.5s display) → fade
|
||
- **Error:** Red X + error message
|
||
|
||
**Accessibility:**
|
||
- `role="status"` - Status indicator
|
||
- `aria-live="polite"` - Status updates
|
||
- `aria-busy="true"` during processing
|
||
|
||
**Design Tokens:**
|
||
- Spinner color: `var(--ai-processing)` (#F59E0B)
|
||
- Text: `text-sm text-secondary` (#6B7280)
|
||
- Animation: Spin 1s linear infinite
|
||
- Respects `prefers-reduced-motion`
|
||
|
||
**Content Guidelines:**
|
||
- Default text: "AI thinking..."
|
||
- Contextual text: "Generating embeddings...", "Reformulating..."
|
||
- Error text: "AI unavailable. Try again later."
|
||
|
||
---
|
||
|
||
### Component Implementation Strategy
|
||
|
||
**Foundation Components (from Radix UI):**
|
||
|
||
Leverage Radix UI primitives with Tailwind styling:
|
||
|
||
| Radix Primitive | Usage in Memento | Custom Styling |
|
||
|----------------|------------------|----------------|
|
||
| Dialog | Reformulation modal, Memory Echo details | Purple border, AI-specific padding |
|
||
| DropdownMenu | Title suggestions, AI Badge menu | Purple text on hover, ✨ icons |
|
||
| Toast | Base for AIToast | Extended with purple border, custom positioning |
|
||
| Switch | AI settings toggles | Default Radix + labels |
|
||
| NavigationMenu | Cahiers sidebar | Active state = purple left border |
|
||
|
||
**Custom Components (IA-specific):**
|
||
|
||
Build 7 custom components on top of Radix primitives:
|
||
|
||
1. **MemoryEchoCard** - Extended AIToast with 2-column note comparison
|
||
2. **SemanticSearchBadge** - Custom badge component (blue styling)
|
||
3. **TitleSuggestionsDropdown** - Radix DropdownMenu + ✨ icons + purple text
|
||
4. **ReformulationModal** - Radix Dialog with 2-column layout
|
||
5. **ProviderIndicator** - Custom status indicator (icon + text + status)
|
||
6. **AIToast** - Extended Radix Toast (purple border, positioning)
|
||
7. **ProcessingIndicator** - Custom spinner + status text
|
||
|
||
**Implementation Approach:**
|
||
|
||
1. **Create IA-specific component variants**
|
||
- Extend Radix components with AI styling
|
||
- Use composition over inheritance
|
||
- Share design tokens (colors, spacing)
|
||
|
||
2. **Use design tokens for consistency**
|
||
- All AI components use `--ai-*` color tokens
|
||
- Spacing from 8px grid (space-2, space-4, etc.)
|
||
- Typography from system fonts scale
|
||
|
||
3. **Follow accessibility patterns**
|
||
- Leverage Radix's built-in ARIA attributes
|
||
- Add custom ARIA for AI-specific content
|
||
- Ensure keyboard navigation (ESC, Tab, Enter)
|
||
- Test with screen readers
|
||
|
||
4. **Create reusable patterns**
|
||
- AIToast wrapper around Radix Toast
|
||
- BaseModal component (extends Dialog) for all modals
|
||
- AIBadge base component (purple border, common props)
|
||
|
||
---
|
||
|
||
### Implementation Roadmap
|
||
|
||
**Phase 1 - Core Components (Week 1-2) - P0**
|
||
|
||
| Component | Priority | User Journey | Rationale |
|
||
|-----------|----------|--------------|-----------|
|
||
| ProviderIndicator | P0 | Max (Privacy) | Essential for user trust, shows AI status |
|
||
| AIToast | P0 | All journeys | Base component for all AI notifications |
|
||
| TitleSuggestionsDropdown | P0 | Alex (Fast Capture) | Most-used AI feature, high user value |
|
||
|
||
**Deliverables:**
|
||
- ✅ ProviderIndicator with local/cloud states
|
||
- ✅ AIToast base component with purple styling
|
||
- ✅ TitleSuggestionsDropdown with 3 options
|
||
- ✅ Design tokens extension (AI colors)
|
||
|
||
**Week 1:** ProviderIndicator, AIToast
|
||
**Week 2:** TitleSuggestionsDropdown + testing
|
||
|
||
---
|
||
|
||
**Phase 2 - AI Features (Week 3-4) - P1**
|
||
|
||
| Component | Priority | User Journey | Rationale |
|
||
|-----------|----------|--------------|-----------|
|
||
| SemanticSearchBadge | P1 | Alex (Search) | Feature 2 (Semantic Search) |
|
||
| ReformulationModal | P1 | Alex (Enhancement) | Feature 3 (Reformulation) |
|
||
| ProcessingIndicator | P1 | All journeys | Feedback during AI operations |
|
||
|
||
**Deliverables:**
|
||
- ✅ SemanticSearchBadge with confidence scores
|
||
- ✅ ReformulationModal with 2-column comparison
|
||
- ✅ ProcessingIndicator with loading/success/error states
|
||
|
||
**Week 3:** SemanticSearchBadge, ProcessingIndicator
|
||
**Week 4:** ReformulationModal + integration
|
||
|
||
---
|
||
|
||
**Phase 3 - Advanced (Week 5) - P2**
|
||
|
||
| Component | Priority | User Journey | Rationale |
|
||
|-----------|----------|--------------|-----------|
|
||
| MemoryEchoCard | P2 | Alex/Max (Aha!) | Feature 4 (Memory Echo) - defining experience but complex |
|
||
|
||
**Deliverables:**
|
||
- ✅ MemoryEchoCard with 2-note comparison
|
||
- ✅ Background processing (cosine similarity)
|
||
- ✅ 👍👎 feedback system
|
||
|
||
**Week 5:** MemoryEchoCard + testing + refinement
|
||
|
||
---
|
||
|
||
**Prioritization Rationale:**
|
||
|
||
**P0 (Critical Path):**
|
||
- **ProviderIndicator:** Trust blocker - Max won't use AI without status visibility
|
||
- **AIToast:** Foundation for all AI notifications
|
||
- **TitleSuggestions:** Highest user value (80% acceptance rate in PRD)
|
||
|
||
**P1 (High Value):**
|
||
- **SemanticSearchBadge:** Key differentiator vs keyword search
|
||
- **ReformulationModal:** Enhancement feature, improves writing quality
|
||
- **ProcessingIndicator:** UX requirement - users need feedback during AI ops
|
||
|
||
**P2 (Strategic):**
|
||
- **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
|
||
|
||
---
|