--- stepsCompleted: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] inputDocuments: - '_bmad-output/planning-artifacts/product-brief-l-ami-fiduciaire-2026-03-10.md' - '_bmad-output/planning-artifacts/prd.md' - '_bmad-output/planning-artifacts/prd-validation-report.md' - '_bmad-output/project-context.md' - 'docs/index.md' - 'docs/project-overview.md' - 'docs/architecture.md' - 'docs/development-guide.md' - 'docs/source-tree-analysis.md' --- # UX Design Specification L'Ami Fiduciaire **Author:** Saad **Date:** 2026-03-11 --- ## Executive Summary ### Project Vision L'Ami Fiduciaire is a practice management orchestration platform for Moroccan fiduciary firms. It sits above existing accounting tools (Sage/JBS) and government portals (SIMPL/Damancom) to orchestrate the complete practice workflow -- tracking deadlines across dozens of clients, coordinating team workload, managing client document exchange, and ensuring nothing falls through the cracks. The platform targets Morocco's ~20,000+ small-to-mid-size fiduciary firms (majority under 10 staff) with a confirmed Experio partnership for distribution. The product is a brownfield project with a Laravel 12 + Vue 3 + Inertia.js stack, using shadcn-vue components and Tailwind CSS 4. Core infrastructure (multi-tenant workspaces, client management, folder/dossier system, client portal, document exchange, messaging, email notifications, 2FA, activity logging) is already built. The MVP adds 5 phases: role system foundation, dashboard separation, collaboration/nudge features, workflow efficiency (bulk operations, advanced filtering), and a full archive system. ### Target Users | Persona | Role | Usage Pattern | Tech Level | Primary Device | |---|---|---|---|---| | **Karim** (Owner/Manager) | Firm owner, 120+ clients, manages team | Morning dashboard check, escalation handling | Moderate | Desktop | | **Rachid** (Chef de Mission) | Supervises 3 workers, 90 dossiers | Team coordination, workload balancing, reassignment | Moderate | Desktop | | **Fatima** (Collaborateur) | Manages 45 client dossiers | All-day power user -- the primary platform user | Moderate | Desktop | | **Hassan** (External Client) | SARL owner, non-technical | Drive-by: click link, upload document, leave | Low | Mobile (phone) | | **Saad** (Platform Admin) | SaaS owner | Platform monitoring, support tickets | High | Desktop | **Design priority:** Fatima is the heaviest daily user and the UX must be optimized for her workflow first. Karim/Rachid need command-center visibility. Hassan needs zero-friction, mobile-first portal interactions. ### Key Design Challenges 1. **Multi-role dashboard complexity** -- One app shell must serve 4 internal roles with dramatically different information needs. Navigation, sidebar, and dashboard content must adapt per role without fragmenting the product experience. 2. **Tables-first, density-first design** -- Moroccan fiduciary professionals work in Excel and think in rows/columns. The PRD mandates "tables over cards" and "practicality-first UI." Every screen must prioritize information density and task speed over visual aesthetics. 3. **Bulk operations at scale** -- Creating declarations for 50 clients simultaneously, scheduling bulk notifications. These power-user flows must be fast yet error-proof, with clear multi-select, type selection, and date picking patterns. 4. **Client portal for non-technical users** -- Hassan is on his phone, not tech-savvy, possibly on the go. The portal must be a single-action page with zero cognitive load: see what's needed, do it, leave. Mobile-first for this surface only. 5. **Information density vs. cognitive overload** -- Owners see 120+ clients, workers see 45+ declarations with deadlines. Dense data tables must use smart color coding, status badges, and priority indicators to enable scanning without overwhelming. 6. **Brownfield constraints** -- 31 existing Vue pages, shadcn-vue component library, Inertia.js page-based navigation patterns. UX design must extend and enhance what's built, not start from scratch. ### Design Opportunities 1. **"Morning command center" moment** -- A transformative dashboard experience where Karim sees his entire firm's status for the first time on one screen. Priority alerts (red/amber/green), deadline countdowns, and team activity create the "aha moment" that drives trial-to-paid conversion. 2. **Moroccan fiscal calendar intelligence** -- Pre-loaded TVA deadlines (20th), CNSS (10th), IS (quarterly) in bulk creation flows. The system knows the calendar so users don't have to remember it. 3. **Progressive disclosure for power features** -- Clean, simple defaults with advanced features (nudge system, archive, advanced filters) accessible but not in the way. Fatima discovers power features as she needs them. 4. **Consistent visual status language** -- A unified color/badge/icon system for declaration statuses across all views (dashboards, tables, archive, portal). Enables instant scanning -- Fatima can assess 45 declarations' health in seconds. ## Core User Experience ### Defining Experience The core product loop for L'Ami Fiduciaire centers on the **declaration status scanning and action cycle**. Fatima (the primary daily user) opens her scoped dashboard, scans her declaration list, identifies what needs attention based on visual status indicators, and takes immediate action -- sending a client notification, updating a status, or escalating to a manager. This scan-identify-act loop happens dozens of times per day and must be optimized for speed and accuracy. For Karim (Owner), the core experience is the **morning command center check** -- a single-screen view of the entire firm's health: which declarations are at risk, which clients are unresponsive, which workers are overloaded. The dashboard-to-action flow (seeing a problem and resolving it in minimal clicks) is the critical interaction to get right. For Hassan (External Client), the core experience is the **single-action portal interaction** -- click a link, see what's needed, do it, leave. The entire interaction should complete in under 60 seconds. ### Platform Strategy | Dimension | Decision | Rationale | |---|---|---| | **Primary platform** | Desktop web (Chrome/Firefox/Safari) | Fiduciary professionals work at desks in offices | | **Secondary platform** | Mobile web (responsive) | Client portal for Hassan; no native app for MVP | | **Input model** | Mouse/keyboard-first (firm users), touch-friendly (portal) | Dense tables and power workflows for professionals, simple tap interactions for clients | | **Offline support** | Not required | Firm users always connected; client portal interactions are brief | | **SPA model** | Inertia.js server-driven pages | Brownfield constraint -- full page transitions, server-side filtering, pagination. No infinite scroll or complex client-side state | ### Effortless Interactions 1. **Status scanning** -- Fatima opens her dashboard and knows in 2 seconds: "3 urgent, 5 on track, 2 waiting on clients." Color/badge visual language eliminates the need to read individual rows. 2. **One-click nudge** -- Karim sees a problem declaration, clicks the nudge icon on the row, selects an employee. Done. No modal forms, no extra navigation. 3. **Bulk declaration creation** -- Select 20 clients via checkboxes, pick declaration type (TVA Mensuel), set deadline (March 20), create. Three steps for 20 declarations. 4. **Client portal upload** -- Hassan clicks email link, sees one sentence explaining what's needed, taps upload, takes photo of document, confirms. Under 60 seconds total. 5. **Filter persistence** -- Fatima sets her preferred filters (Status = En cours, Assignee = Me) once. Filters persist across navigation until explicitly cleared. ### Critical Success Moments | Moment | Persona | Description | Impact | |---|---|---|---| | **"Morning command center"** | Karim | First time seeing all 120+ clients' status on one screen | Trial-to-paid conversion trigger | | **"My list is clear"** | Fatima | End of day, all declarations updated, all notifications sent | Daily satisfaction, retention | | **"30-second upload"** | Hassan | Click link, upload document, see confirmation | Client portal adoption | | **"Nothing fell through"** | Karim | End of month, zero penalty notices across all clients | Long-term retention moment | | **"I can see everything"** | Rachid | Reassigns declaration from absent worker in 2 clicks | Team coordination value proof | ### Experience Principles 1. **Density is clarity** -- More information on screen is better, not worse. Accountants are trained to read dense data. The UX removes noise, not data. Every row, badge, and number earns its place. 2. **Action at the point of recognition** -- The moment a user recognizes something needs attention, the action should be available right there. Inline actions, row-level buttons, contextual menus. No navigate-to-another-page-to-do-the-thing. 3. **The system remembers, so you don't have to** -- Fiscal calendar awareness, filter persistence, status history, audit trails. The platform carries the cognitive load that currently lives in users' heads and Excel sheets. 4. **Zero-friction boundaries** -- Every boundary crossing (firm-to-client portal, dashboard-to-declaration detail, active-to-archive) should feel seamless. No dead ends, no "where was I?" moments. 5. **French-native, Morocco-aware** -- Not a translated product. UI language, date formats (dd/mm/yyyy), currency (MAD), fiscal calendar, and professional terminology are natively Moroccan French. ## Desired Emotional Response ### Primary Emotional Goals | Persona | Primary Emotion | Emotional Shift | |---|---|---| | **Karim** (Owner) | In control, confident | From anxiety ("what's falling through?") to mastery ("I see everything") | | **Fatima** (Worker) | Competent, unburdened | From overwhelmed ("45 clients in my head") to methodical ("I work the list") | | **Hassan** (Client) | Respected, not confused | From friction ("another system to figure out") to ease ("that was quick") | | **Rachid** (Manager) | Effective, empowered | From relay ("WhatsApp forwarding") to leader ("I coordinate, I don't chase") | ### Emotional Journey Mapping | Stage | Desired Emotion | Anti-Emotion (Avoid) | |---|---|---| | First discovery / signup | Curiosity, "this is made for me" | Skepticism, "just another tool" | | Onboarding (first 30 min) | Confidence, progressive competence | Overwhelm, confusion | | First morning dashboard | Relief, revelation | Information overload | | Daily use (Fatima's loop) | Flow state, productive rhythm | Tedium, friction | | Bulk operations | Power, efficiency | Fear of mistakes at scale | | Client portal (Hassan) | Ease, "that was quick" | Confusion, abandonment | | Something goes wrong | Trust, "I can fix this" | Panic, blame, data loss fear | | End of month review | Pride, accomplishment | Dread, surprise penalties | | Returning next day | Familiarity, continuity | Disorientation, "where was I?" | ### Micro-Emotions - **Confidence over confusion** -- Every screen immediately answers "where am I, what can I do here?" through role-based views, clear headings, and breadcrumbs. - **Trust over skepticism** -- Data integrity signals throughout: timestamps, audit trails, upload confirmations, action feedback. Never leave users wondering if something worked. - **Accomplishment over frustration** -- Progress indicators, completion states, visual reward as task lists clear through the day. Fatima's dashboard shifting from red to green is the emotional payoff. - **Calm over anxiety** -- During peak season (bilan Jan-Mar), the platform reduces stress. No alarm fatigue, smart priority levels, achievable daily task scope. Not everything can be red. ### Design Implications | Desired Emotion | UX Design Approach | |---|---| | **In control** (Karim) | Dashboard summary cards with real-time counts, color-coded priority system, no hidden information | | **Unburdened** (Fatima) | Scoped view showing only assigned work, clear next-action indicators, persistent filters | | **Respected** (Hassan) | Single-purpose portal pages, large touch targets, plain French copy, immediate confirmation feedback | | **Effective** (Rachid) | One-click reassignment, team workload overview, nudge system with direct-link notifications | | **Confident** (all internal) | Consistent layout patterns, breadcrumb navigation, undo/correction flows, visible activity logs | | **Calm during peak** (all firm) | Smart alert prioritization, deadline countdown gradients (green to amber to red), manageable daily scope | | **Trust** (all) | Timestamps on every action, explicit confirmations, archive as preservation (not deletion), accessible audit trail | ### Emotional Design Principles 1. **Professional calm, not consumer excitement** -- This is a daily-use B2B tool for accountants during high-stress periods. The design should feel reliable, structured, and calming -- like a well-organized filing cabinet, not a flashy app. 2. **Earned urgency only** -- Red alerts, warning badges, and urgent indicators must be meaningful and sparse. If the system cries wolf, users stop trusting it. Priority levels (critical/warning/info) must reflect real deadline proximity. 3. **Collaborative, not surveillance** -- Activity logs and nudges exist to coordinate work, not monitor employees. The nudge system should feel like a helpful tap on the shoulder, not a manager looking over your shoulder. 4. **Immediate feedback, always** -- Every user action gets visible confirmation. Uploads confirmed, status changes reflected, nudges acknowledged. Silence creates anxiety; feedback creates trust. 5. **Graceful degradation of pressure** -- As deadlines approach, the UI should communicate increasing urgency gradually (green to amber to red) rather than suddenly. Users should never be surprised by an overdue declaration -- the system warned them progressively. ## UX Pattern Analysis & Inspiration ### Inspiring Products Analysis #### 1. Linear (Project/Issue Tracking) **Why relevant:** Linear's issue tracker is the closest UX analog to Fatima's declaration list -- dense rows of work items with statuses, assignees, priorities, and deadlines. It's the gold standard for "tables-first, keyboard-driven B2B SaaS." **What they do well:** - **Scannable list views** -- Status icons (colored circles), priority indicators, and assignee avatars are visible at the row level without expanding anything. One glance tells you the state of each item. - **Inline actions** -- Right-click context menus and keyboard shortcuts for status changes, assignment, priority updates. No page navigation required for common actions. - **Filter bar with persistence** -- Filters sit above the list, stay active across sessions, and can be saved as custom views. - **Progressive disclosure** -- Simple by default, powerful when you dig in. New users see a clean list; power users build custom workflows. - **Sidebar navigation** -- Collapsible sidebar with workspace-level navigation. Clean, not cluttered. **Transferable to L'Ami Fiduciaire:** Declaration list UX, filter persistence, inline row actions, sidebar navigation pattern, status icon system. #### 2. Excel / Google Sheets (The Users' Mental Model) **Why relevant:** This is how Fatima and Karim currently work. Excel is not a product to emulate but a mental model to respect. Users think in rows, columns, sorting, and filtering. Any table in L'Ami Fiduciaire must feel at least as natural as a spreadsheet. **What they do well:** - **Information density** -- Maximum data per screen. No wasted whitespace. Users are trained to scan dense grids. - **Sort and filter as primary interaction** -- Click a column header to sort, filter dropdowns on columns. This is muscle memory. - **Cell-level editing** -- Click a cell, change the value, move on. Minimal friction for status updates. - **Familiarity** -- Zero learning curve for the basic interaction model. **Transferable to L'Ami Fiduciaire:** Table density expectations, column sorting, filter-first navigation, minimal whitespace in data views. The UX should feel like "Excel that thinks for you" -- same density, but with status intelligence, deadline awareness, and collaboration built in. #### 3. Sage (Accounting Software -- The Legacy Baseline) **Why relevant:** Every firm user has Sage open daily. It's a Windows-era desktop application with a functional but dated UI. Understanding what users tolerate (and what frustrates them) about Sage informs what L'Ami Fiduciaire should avoid. **What they tolerate:** - Dense forms with many fields -- accountants are used to data-heavy screens - Menu-driven navigation (File > Client > Dossier) -- hierarchical mental model - Modal dialogs for data entry -- not ideal, but familiar **What frustrates them:** - No web access, no collaboration, no real-time updates - No dashboard or overview -- you must drill into each client individually - No notification system -- everything is manual recall - Dated visual design that feels like work, not empowerment **Lesson for L'Ami Fiduciaire:** Don't try to look like Sage. But respect the density and data-first expectations that Sage users carry. The platform should feel modern and web-native while maintaining the information density that accountants expect. #### 4. Experio (AI Pre-Accounting -- The Partner Product) **Why relevant:** Confirmed partnership. Many L'Ami Fiduciaire users will also be Experio users. Their UX is a cautionary reference. **What to learn from their weaknesses:** - Bad UX on core pages creates an opportunity -- L'Ami Fiduciaire can set a higher standard that makes the combined Experio + L'Ami stack feel premium - If Experio's onboarding works (landing page is good), users arrive with expectations that the product behind the landing page will be equally polished - Integration UX (future) must be seamless enough to compensate for Experio's own UX gaps **Lesson for L'Ami Fiduciaire:** Be the product in the stack that users actually enjoy using. Set the UX bar for the Moroccan fiduciary SaaS ecosystem. ### Transferable UX Patterns **Navigation Patterns:** - **Collapsible sidebar with role-driven sections** (from Linear) -- Sidebar shows different nav items based on role. Owner/Manager sees "Dashboard, Clients, Declarations, Archive, Team, Settings." Worker sees "Dashboard, My Declarations, Archive, Settings." Clean separation without separate apps. - **Breadcrumb trail for depth navigation** (standard B2B) -- Dashboard > Client Benani > TVA Janvier 2026. Always know where you are, always able to go back. **Interaction Patterns:** - **Inline status updates on table rows** (from Linear) -- Click a status badge directly on the declaration row to cycle through statuses or open a dropdown. No need to open the full detail page for common actions. - **Row-level action menu** (from Linear) -- Three-dot menu or right-click on any declaration row reveals: Edit, Nudge, Reassign, View Detail, Archive. Actions at the point of recognition. - **Bulk selection with action bar** (from Gmail/Linear) -- Checkboxes on rows, floating action bar appears: "23 selected: Create Declarations | Send Notifications | Change Status." **Visual Patterns:** - **Color-coded status badges** (from Linear/GitHub) -- Consistent colored dots/pills for declaration statuses across all views. Same color = same meaning everywhere. - **Deadline proximity indicators** (unique to L'Ami) -- Days-remaining counter with color gradient: green (>7 days) → amber (3-7 days) → red (<3 days) → dark red (overdue). More informative than a simple date. - **Summary cards above tables** (from dashboard patterns) -- "12 En cours | 3 En retard | 5 En attente client | 2 Urgent" as clickable cards that filter the table below. **Data Patterns:** - **Server-side pagination with page size control** (Inertia constraint) -- Standard pagination (25/50/100 rows per page) with persistent preference. Respects the server-driven SPA model. - **Column sorting** (from Excel mental model) -- Click column headers to sort. Users expect this from their spreadsheet habits. - **Persistent filter bar** (from Linear) -- Filter pills visible above the table, removable with X, persisted in session/URL params. ### Anti-Patterns to Avoid 1. **Card-based layouts for data lists** -- Cards waste space and break the row-scanning mental model accountants rely on. Declarations, clients, and archive items must be table rows, not cards. Cards are acceptable only for dashboard summary metrics. 2. **Over-modalization** -- Opening a modal for every action (edit status, send notification, reassign) creates friction. Prefer inline edits, dropdowns, and popovers over full modals. Reserve modals for destructive or multi-step actions only (bulk creation, delete confirmation). 3. **Hidden navigation behind hamburger menus** -- Desktop users expect a visible sidebar. Never hide the primary navigation behind a toggle on desktop viewports. The sidebar is always visible (collapsible to icons is acceptable). 4. **Alarm fatigue through over-notification** -- Not every declaration needs a red badge. Priority indicators must use 3-4 levels (critical/warning/info/neutral) with clear thresholds tied to deadline proximity. Default state is calm. 5. **Onboarding wizards that block usage** -- Multi-step setup wizards create friction. Prefer progressive onboarding: let users into the product immediately, guide them contextually. "Add your first client" prompt on an empty client list is better than a 5-step wizard. 6. **Whitespace-heavy "modern" design** -- Fiduciary professionals want density, not aesthetics. Large padding, oversized cards, and spacious layouts feel wasteful to users who work in Excel all day. Keep spacing tight and purposeful. ### Design Inspiration Strategy **What to Adopt:** - Linear's list view UX (scannable rows, inline actions, filter persistence) → Declaration and client list views - Linear's sidebar navigation (collapsible, workspace-scoped) → App shell navigation - Summary-cards-above-table pattern → Dashboard command center and list view headers - Color-coded status badge system → Universal declaration status language **What to Adapt:** - Excel's density expectations → Adapt for web (slightly more spacing than a spreadsheet, but far less than typical SaaS) - Linear's keyboard shortcuts → Start with mouse-first, add keyboard shortcuts as power-user feature post-MVP - Gmail's bulk selection bar → Adapt for declaration bulk operations (create, notify, status change) **What to Avoid:** - Experio's core page UX patterns → Set a higher bar - Sage's modal-heavy, menu-driven navigation → Use modern web navigation (sidebar + breadcrumbs) - Card layouts for data → Tables everywhere except dashboard summaries - Consumer SaaS aesthetic (Notion-like spaciousness) → Too sparse for accountant workflows ## Design System Foundation ### Design System Choice **Selected:** shadcn-vue (reka-ui) + Tailwind CSS 4 -- extending the existing brownfield design system. This is a brownfield project with 20+ shadcn-vue component groups already installed and 31 Vue pages built on them. The design system choice is to **confirm, extend, and customize** what exists rather than replace it. **Component Library:** shadcn-vue (headless reka-ui primitives with Tailwind styling) **Styling Framework:** Tailwind CSS 4 with CVA (Class Variance Authority) for component variants **Icons:** Lucide (lucide-vue-next) **Utility Layer:** `cn()` helper (clsx + tailwind-merge) in `resources/js/lib/utils.ts` ### Rationale for Selection 1. **Brownfield reality** -- 31 Vue pages and 20+ component groups already built on shadcn-vue. Migration cost would exceed any benefit of an alternative system. 2. **Density-compatible** -- Headless primitives with Tailwind styling allow full control over spacing and density. Unlike Material Design or Ant Design, there's no opinionated spacing to fight against. 3. **Accessibility built-in** -- reka-ui handles ARIA attributes, keyboard navigation, and focus management at the primitive level. Accessible by default without extra work. 4. **Tailwind 4 synergy** -- CVA-based component variants make it straightforward to create "compact" and "dense" variants of existing components for data-heavy views. 5. **No vendor lock-in** -- Components live in the project (`resources/js/components/ui/`), not in `node_modules`. Full ownership and customization capability. 6. **Team familiarity** -- Both developers (Saad + Ilyas) already work with this stack daily. Zero learning curve. ### Implementation Approach **Extend, don't replace:** - Existing `resources/js/components/ui/` components remain untouched (auto-generated via `npx shadcn-vue`) - New custom components built in `resources/js/components/` (app-level) following the same Tailwind + CVA patterns - Dense/compact variants added via CVA variant props (e.g., `size="compact"`) rather than separate components **Component organization:** - `resources/js/components/ui/` -- shadcn-vue base components (do not modify) - `resources/js/components/` -- app-level business components (ClientForm, FolderForm, etc.) - New dashboard, filter, and notification components added to `resources/js/components/` ### Customization Strategy **1. Design Tokens (via Tailwind CSS 4 theme):** - Declaration status colors (universal across all views) - Priority level colors (deadline proximity gradient) - Alert severity colors (critical/warning/info/neutral) - Spacing scale optimized for density (tighter than default Tailwind) **2. Component Variants to Create:** - **Dense Table** -- Compact row height, tighter padding, optimized for 25-50 rows visible without scrolling - **Status Badge** -- Color-coded pill with consistent mapping to declaration statuses - **Priority Indicator** -- Days-remaining counter with deadline proximity color - **Summary Card** -- Dashboard metric card with count, label, and click-to-filter behavior - **Filter Bar** -- Persistent filter pills with dropdown selectors and clear-all action - **Nudge Button** -- Inline row-level action for one-click team coordination - **Bulk Action Bar** -- Floating bar that appears on multi-select with available bulk operations **3. Layout Customizations:** - Sidebar navigation adapted for role-driven sections - Dashboard grid layout for command center summary cards - Table-first page templates for Clients, Declarations, and Archive views - Single-action portal page template for client-facing interactions ## Defining Core Experience ### The Defining Interaction L'Ami Fiduciaire's defining experience is: **"Open the app and instantly know what needs your attention across all your clients."** This is the interaction that drives trial-to-paid conversion, daily engagement, and word-of-mouth referral. Karim describes it as: "I open L'Ami Fiduciaire and I see everything -- which clients are at risk, which declarations are overdue, who needs to submit documents. Nothing surprises me." For Fatima: "I log in and my list tells me exactly what to do today." ### User Mental Model | Persona | Mental Model | Primary Question | Design Implication | |---|---|---|---| | **Karim** (Owner) | Thinks in "risk" | "What's about to go wrong?" | Exception-based dashboard: surface problems first, details on drill-down | | **Fatima** (Worker) | Thinks in "task lists" | "What do I need to do today?" | Ordered action list: next action per client, sorted by urgency | | **Hassan** (Client) | Thinks in "requests" | "What do they want from me?" | Single-action page: one clear instruction, one button | **Key mental model constraints:** - Karim expects a command center that surfaces exceptions, not an exhaustive inventory. Summary cards for the big picture, alert lists for what needs attention. - Fatima expects Excel-like table interactions: sort, filter, scan rows. Table patterns must support this muscle memory. - Hassan needs explicit, action-oriented copy. "Telecharger votre releve bancaire de janvier" not "Documents requis." ### Success Criteria | Criterion | Measure | Threshold | |---|---|---| | Time to situational awareness | Karim understands firm status after opening dashboard | < 10 seconds | | Time to first action | Fatima identifies and starts working on most urgent item | < 30 seconds from login | | Task completion rate | Hassan completes portal action without help | > 95% success rate | | Scan accuracy | Fatima identifies 3 most urgent declarations from list of 45 | Instant via visual status language | | Zero-miss rate | Priority alerts catch all approaching deadlines | 100% coverage | ### Pattern Innovation The core experience uses **established interaction patterns combined in novel ways:** - **Established:** Data tables with sorting/filtering (Excel mental model), status badges with color coding (Linear/GitHub), dashboard summary cards (standard B2B SaaS), bulk selection with action bars (Gmail) - **Novel combination:** Deadline proximity indicators that auto-calculate days remaining and color-code based on Moroccan fiscal calendar awareness - **Novel combination:** Summary cards that double as table filters -- clicking "3 En retard" filters the table below to overdue declarations only - **Novel combination:** Role-based dashboard layouts serving different mental models (Karim's risk-first vs. Fatima's task-first) from the same underlying data No user education required. Every pattern feels familiar to users of Excel, email, and basic web apps. The intelligence is in the system, not in asking users to learn new interactions. ### Experience Mechanics **The Core Loop: Open → Scan → Act → Confirm** **1. Initiation (Opening the App):** - Owner/Manager lands on **Command Center Dashboard**: summary cards (active clients, declarations by status, overdue count, pending client actions), priority alert list, recent activity feed - Worker lands on **Scoped Dashboard**: same structure filtered to assigned clients only, "My Declarations" as primary view - Data is server-rendered (Inertia) -- no loading spinners for primary content **2. Scanning (Identifying What Needs Attention):** - Visual hierarchy: red = overdue (act now), amber = approaching deadline (plan), green = on track (ignore), gray = completed/archived - Summary cards are clickable filters: click "3 En retard" → table filters to overdue declarations - Column sorting on all data columns, default sort by deadline ascending (most urgent first) **3. Acting (Taking Action):** - Inline status change: click status badge → dropdown → select new status → instant update with toast confirmation - One-click nudge: click nudge icon → popover with assignee → click send → toast confirmation, no page navigation - Bulk operations: select rows via checkboxes → floating action bar → choose action → confirmation → execute → toast with count **4. Confirming (Knowing You're Done):** - Summary cards update as statuses change ("3 En retard" → "2 En retard") - Task list visually clears through the day -- urgent count decreases as work progresses - End-of-day state: "0 En retard, 0 Actions en attente" -- the "nothing fell through" emotional payoff ## Visual Design Foundation ### Color System **Base Theme (Existing -- Confirmed):** The brownfield codebase uses shadcn-vue "new-york-v4" style with OKLCH color tokens. The existing palette serves as the foundation: - **Primary:** Blue/purple (`oklch(0.488 0.243 264.376)`) -- main interactive elements, active states, sidebar highlights - **Primary Foreground:** Near-white (`oklch(0.97 0.014 254.604)`) -- text on primary backgrounds - **Destructive:** Red (`oklch(0.577 0.245 27.325)`) -- delete actions, critical errors - **Background:** White (`oklch(1 0 0)`) -- page backgrounds - **Foreground:** Near-black (`oklch(0.141 0.005 285.823)`) -- primary text - **Muted:** Light gray (`oklch(0.967 0.001 286.375)`) -- secondary backgrounds - **Muted Foreground:** Medium gray (`oklch(0.552 0.016 285.938)`) -- secondary text, labels - **Border:** Light gray (`oklch(0.92 0.004 286.32)`) -- dividers, input borders - **Dark mode:** Full dark theme variant with inverted tokens, togglable via system/user preference **New Semantic Colors (To Add):** Declaration status colors -- the universal visual language used across dashboards, tables, archive, and portal: | Status | Color Token | OKLCH Value | Usage | |---|---|---|---| | **Overdue** (En retard) | `--status-overdue` | Red -- high chroma, clearly urgent | Declarations past deadline | | **Urgent** (Urgent) | `--status-urgent` | Dark amber/orange -- approaching deadline | Declarations due within 3 days | | **In Progress** (En cours) | `--status-in-progress` | Blue (primary) | Active work, normal state | | **Waiting Client** (En attente client) | `--status-waiting` | Amber/yellow | Blocked on external action | | **Completed** (Termine) | `--status-completed` | Green -- muted, not celebratory | Successfully closed | | **Draft** (Brouillon) | `--status-draft` | Gray (muted foreground) | Not yet active | | **Archived** (Archive) | `--status-archived` | Light gray, desaturated | Read-only historical | Priority/deadline proximity gradient: | Proximity | Color | Threshold | |---|---|---| | **Safe** | Green | > 7 days remaining | | **Approaching** | Amber | 3-7 days remaining | | **Urgent** | Orange-red | 1-3 days remaining | | **Overdue** | Red | Past deadline | Alert severity levels: | Level | Color | Usage | |---|---|---| | **Critical** | Red (destructive) | Overdue declarations, system errors | | **Warning** | Amber | Approaching deadlines, missing documents | | **Info** | Blue (primary) | Nudge received, status update, new upload | | **Neutral** | Gray (muted) | Activity log entries, completed items | ### Typography System **Primary Typeface:** Instrument Sans (already configured) - Clean, modern sans-serif with excellent readability at small sizes - Appropriate for dense data tables and professional B2B context - Full stack fallback: `Instrument Sans, ui-sans-serif, system-ui, sans-serif` **Type Scale (optimized for density):** | Level | Size | Weight | Line Height | Usage | |---|---|---|---|---| | **Page Title** | 1.5rem (24px) | 600 (semibold) | 1.33 | Page headings (Declarations, Clients, Archive) | | **Section Title** | 1.125rem (18px) | 600 (semibold) | 1.33 | Dashboard section headers, card titles | | **Card Metric** | 1.5rem (24px) | 700 (bold) | 1.2 | Summary card numbers ("12", "3", "45") | | **Table Header** | 0.75rem (12px) | 500 (medium) | 1.5 | Column headers, uppercase tracking | | **Table Body** | 0.8125rem (13px) | 400 (regular) | 1.5 | Table row content -- slightly smaller than default for density | | **Body** | 0.875rem (14px) | 400 (regular) | 1.5 | General content, form labels | | **Small/Caption** | 0.75rem (12px) | 400 (regular) | 1.5 | Timestamps, metadata, secondary info | | **Badge** | 0.6875rem (11px) | 500 (medium) | 1.2 | Status badges, tags, counts | **Density note:** Table body text at 13px (not the default 14px) allows approximately 20% more rows visible without scrolling, directly supporting our "density is clarity" principle. This small reduction is still readable on standard monitors. ### Spacing & Layout Foundation **Base Spacing Unit:** 4px (Tailwind default) **Density Strategy:** Use tighter spacing in data-heavy views, standard spacing in forms and settings. | Context | Spacing Approach | |---|---| | **Dashboard summary cards** | Standard padding (p-4/p-6), comfortable spacing between cards | | **Data tables (dense)** | Compact padding: py-2 px-3 per cell (not default py-4). Reduced row height to show 25-50 rows without scrolling | | **Filter bar** | Compact: gap-2 between filter pills, py-1.5 px-3 per pill | | **Forms** | Standard spacing: gap-4 between fields, comfortable padding | | **Portal pages** | Generous spacing: p-6/p-8, large touch targets (min 44px), mobile-friendly | | **Sidebar navigation** | Compact: py-1.5 px-3 per nav item, visually tight but clickable | **Layout Grid:** - **Dashboard:** CSS Grid -- 4-column layout for summary cards, full-width table below - **List views (Clients, Declarations):** Full-width table with filter bar above - **Detail pages:** Two-column layout (main content + sidebar with metadata/actions) - **Portal pages:** Single-column, centered, max-width 480px (mobile-optimized) - **Sidebar:** Fixed 240px collapsed to 64px (icon-only). Always visible on desktop. **Border Radius (Existing):** - Base: 0.65rem -- kept for buttons, cards, inputs - Badges/pills: full rounded (rounded-full) for status indicators - Tables: square corners (rounded-none) -- tables should feel sharp and data-like ### Accessibility Considerations **Color Contrast:** - All text meets WCAG 2.1 AA standard (4.5:1 for normal text, 3:1 for large text) - Status colors must be distinguishable without relying solely on color -- pair with icons or text labels - OKLCH color space (already used) provides perceptually uniform colors, improving accessibility **Color Blindness:** - Status system uses both color AND shape/icon: overdue = red + warning triangle, completed = green + checkmark, waiting = amber + clock - Never use red/green distinction alone -- always paired with secondary visual cue **Keyboard Navigation:** - reka-ui (shadcn-vue foundation) provides keyboard navigation for all interactive components by default - Focus rings visible (existing ring tokens configured) - Tab order follows visual layout **Text Readability:** - Minimum body text size: 13px (table dense) / 14px (general) - Line height minimum: 1.5 for body text, 1.33 for headings - Instrument Sans has excellent x-height for readability at small sizes **Dark Mode:** - Full dark theme already configured with OKLCH tokens - Status colors must maintain distinguishability and contrast in both light and dark modes - New semantic color tokens will include both light and dark variants ## Design Direction Decision ### Design Directions Explored Four distinct visual directions were generated and presented via an interactive HTML showcase (`ux-design-directions.html`): 1. **Linear Dense** — Ultra-compact, keyboard-first, minimal chrome, maximum data density 2. **Command Center Dashboard** — Bold KPI cards, full sidebar, activity/alerts panels, strong visual hierarchy 3. **Balanced Professional** — Standard-density tables, prominent filter bars, clean spacing, professional tone 4. **Split-View Action** — Master-detail layout, persistent context panel, action-oriented sidebar Each direction applied the established visual foundation (OKLCH color tokens, Instrument Sans, shadcn-vue components) in different layout and density configurations. ### Chosen Direction **Hybrid: "Command Professional"** — A combination of Direction 2 (Command Center Dashboard) and Direction 3 (Balanced Professional). **Key elements from Command Center Dashboard:** - Large KPI summary cards prominently displayed on dashboard views - Full sidebar navigation with logically grouped sections (Clients, Declarations, Archive, Team, Settings) - Activity feed and alerts panel for real-time operational awareness - Bold visual hierarchy with distinct information zones **Key elements from Balanced Professional:** - Standard-density data tables with comfortable row height (~48px) - Persistent filter bar above all list views for quick filtering - Clean, balanced spacing (not ultra-dense, not airy) — professional middle ground - Restrained color application — primary blue accents on interactive elements only ### Design Rationale - **Dashboard pages** benefit from Command Center's bold KPI cards and activity panels — fiduciary managers (Chef de Mission) need at-a-glance operational status - **List/table pages** benefit from Balanced Professional's readable density — workers processing many dossiers need comfortable scanning without fatigue - **The full sidebar** supports the deep navigation structure (Clients, Declarations, Archive, Team, Settings) without hiding sections behind hamburger menus - **Standard density tables** with persistent filters align with the "scan-decide-act" core experience — users scan filtered lists, decide on priority, and act inline - The combination respects the Moroccan accounting context where precision and clarity are paramount, while keeping the interface modern and approachable ### Implementation Approach - **Layout structure:** Fixed full sidebar (240px collapsed to icon-only on mobile) + main content area with top breadcrumb bar - **Dashboard pattern:** CSS Grid for KPI card rows (auto-fill, minmax 280px) + two-column layout for activity feed + deadline alerts - **Table pattern:** shadcn-vue DataTable with sticky header, persistent filter bar (Combobox + DateRangePicker + Search), inline row actions (dropdown menu) - **Responsive strategy:** Sidebar collapses to overlay drawer on mobile; KPI cards stack single-column; tables switch to card-based list view below 768px - **Component density:** Use shadcn-vue default sizing (not `size="sm"`) for comfortable touch targets and readability; compact mode available as user preference toggle ## User Journey Flows ### Journey 1: Owner/Manager Morning Dashboard (Scan-Decide-Act) **Entry Point:** User logs in or opens the app → lands on role-appropriate dashboard **Flow Summary:** The dashboard is the operational command center. Owners and Managers share the same view (all clients, all declarations). The flow follows the "scan-decide-act" pattern established as the core experience. ```mermaid flowchart TD A[Login / Open App] --> B[Dashboard Loads] B --> C[KPI Summary Cards] C --> C1[Overdue Declarations - RED] C --> C2[Due This Week - AMBER] C --> C3[Waiting for Client - BLUE] C --> C4[On Track - GREEN] C1 --> D{Click KPI Card} C2 --> D C3 --> D C4 --> D D --> E[Filtered Declaration List] E --> F{Scan & Decide} F --> G[Nudge Worker] F --> H[Reassign Declaration] F --> I[View Declaration Detail] F --> J[Bulk Select & Act] G --> G1[One-Click Nudge Notification] G1 --> K[Return to List] H --> H1[Select New Assignee] H1 --> H2[Confirm Reassignment] H2 --> K I --> I1[View Status & Documents] I1 --> I2{Action Needed?} I2 -->|Yes| I3[Take Action from Detail] I2 -->|No| K I3 --> K J --> J1[Select Multiple Rows] J1 --> J2[Bulk Action Menu] J2 --> J3[Confirm Bulk Action] J3 --> K K --> F B --> L[Activity Feed Panel] L --> L1[Recent Changes Stream] L1 --> L2{Requires Attention?} L2 -->|Yes| I L2 -->|No| M[Continue Scanning] B --> N[Alerts Panel] N --> N1[Deadline Alerts] N --> N2[Missing Documents] N --> N3[Unread Client Messages] ``` **Key Interaction Details:** - **KPI cards as filters:** Clicking a KPI card filters the declaration table below — no page navigation needed - **Inline row actions:** Hover a declaration row → action icons appear (nudge, reassign, view detail) - **Nudge = one click:** No modal, no message composition — instant notification sent, toast confirms - **Activity feed:** Right-side panel showing real-time changes (document uploads, status updates, reassignments) - **Alerts panel:** Below KPI cards or in sidebar — sorted by urgency, each alert links directly to the relevant declaration ### Journey 2: Worker Daily Workflow (Filter-Process-Update) **Entry Point:** Worker logs in → sees scoped dashboard (only their assigned clients/declarations) **Flow Summary:** Workers focus on processing declarations efficiently. Their flow is a tight loop: filter by priority, check what's needed, notify clients for missing docs, process ready declarations, update statuses. ```mermaid flowchart TD A[Login] --> B[Worker Dashboard] B --> C[Scoped KPI Cards - My Declarations Only] C --> D[Filtered Declaration List] D --> E{Filter by Priority} E --> E1[Overdue First] E --> E2[Due This Week] E --> E3[Waiting for Documents] E --> E4[Ready to Process] E1 --> F{For Each Declaration} E2 --> F E3 --> G[Select Missing-Docs Declarations] E4 --> H[Open Declaration Detail] F --> F1{Status?} F1 -->|Missing Docs| G F1 -->|Docs Ready| H F1 -->|In Progress| H G --> G1[Select Multiple Declarations] G1 --> G2[Bulk Notify Clients] G2 --> G3[Email Sent to Each Client with Token Link] G3 --> G4[Status Auto-Updates to 'Client Notified'] G4 --> D H --> H1[View Declaration Details] H1 --> H2[Download Client Documents] H2 --> H3[Process in Sage/JBS] H3 --> H4[Return to L'Ami Fiduciaire] H4 --> H5[Update Declaration Status] H5 --> H6{New Status} H6 -->|Completed| H7[Mark as Filed] H6 -->|Blocked| H8[Add Note + Flag Issue] H6 -->|In Progress| D H7 --> D H8 --> D B --> I[Notification Badge] I --> I1{Notification Type} I1 -->|Nudge from Manager| I2[View Nudged Declaration] I1 -->|Client Upload| I3[View New Document] I1 -->|Reassignment| I4[New Declaration Added to List] I2 --> H I3 --> H I4 --> D ``` **Key Interaction Details:** - **Scoped view:** Workers only see their assigned declarations — no information overload - **Bulk notify:** Select multiple "waiting for docs" declarations → one click sends personalized emails to each client - **Status updates:** Dropdown or inline button to change status — no separate form or modal - **Notification badge:** Sidebar icon shows count — clicking opens notification panel with direct links - **Client upload awareness:** When a client uploads via portal, the worker's list updates in real-time (or on next refresh) with a visual indicator ("New document") ### Journey 3: Client Document Upload (Zero-Friction Portal) **Entry Point:** Client receives email notification with "Voir la demande" button containing token link **Flow Summary:** The client portal is intentionally minimal — no account, no login, no navigation. Single-purpose: see what's needed, upload it, done. ```mermaid flowchart TD A[Client Receives Email] --> B[Clicks 'Voir la demande' Button] B --> C[Token-Authenticated Portal Page Loads] C --> D[Portal Shows:] D --> D1[Firm Name & Logo] D --> D2[Declaration Type & Period] D --> D3[Documents Requested - Checklist] D --> D4[Upload Zone] D --> D5[Message Thread with Firm] D4 --> E{Upload Document} E --> E1[Drag & Drop or Tap to Browse] E1 --> E2[File Selected] E2 --> E3[Upload Progress Bar] E3 --> E4{Upload Success?} E4 -->|Yes| E5[Document reçu. Merci.] E4 -->|No| E6[Error Message + Retry] E6 --> E1 E5 --> F{More Documents Needed?} F -->|Yes| D3 F -->|No| G[All Documents Submitted] G --> G1[Thank You Message] G1 --> G2[Page Can Be Closed] D5 --> H[View Messages from Firm] H --> H1[Reply to Message] H1 --> H2[Message Sent Confirmation] H2 --> D C --> I[Token Expired or Invalid] I --> I1[Friendly Error Page] I1 --> I2[Contact Your Accountant Message] ``` **Key Interaction Details:** - **No authentication wall:** Token in URL = instant access. No signup, no password, no friction - **Mobile-first layout:** Large tap targets, single-column layout, camera-friendly upload (photo of documents) - **Progress feedback:** Upload progress bar → success checkmark → remaining items count updates - **Document checklist:** Each required document shown as a checklist item — green check when uploaded - **Messaging:** Simple thread view — client can ask questions, firm can clarify requests - **Token expiry:** Graceful error with clear "contact your accountant" message — no dead ends ### Journey 4: Declaration Lifecycle (Cross-Role Flow) **Entry Point:** Owner/Manager creates declaration(s) → flows through assignment, client notification, document collection, processing, and filing **Flow Summary:** This is the end-to-end lifecycle showing how a declaration moves through the system, touching all roles. ```mermaid flowchart TD A[Owner/Manager: Create Declaration] --> A1{Creation Type} A1 -->|Single| A2[Select Client + Type + Deadline] A1 -->|Bulk| A3[Select Multiple Clients + Type + Deadline] A2 --> B[Assign to Worker] A3 --> B B --> C[Status: created] C --> D[Worker Sees in Dashboard] D --> E{Documents Needed?} E -->|Yes| F[Worker Triggers Client Notification] E -->|No| K[Worker Begins Processing] F --> F1[Status: en_attente_client] F1 --> G[Client Receives Email] G --> H[Client Uploads via Portal] H --> I[Worker Notified of Upload] I --> J[Worker Downloads & Reviews] J --> J1{Documents OK?} J1 -->|Yes| K J1 -->|No| J2[Worker Messages Client via Portal] J2 --> F1 K --> K1[Status: en_cours] K1 --> L[Worker Processes in Sage/JBS] L --> M[Worker Updates Status] M --> M1[Status: termine] M1 --> N[Declaration Complete] N --> N1[Status: ferme] N1 --> O[Auto-Archive] O --> O1[Status: archive] subgraph Edge Cases EC1[Manager Nudges Worker] --> D EC2[Manager Reassigns Declaration] --> B EC3[Worker Edits Declaration Type] --> EC4[Activity Log Updated] EC4 --> D EC5[Deadline Approaching] --> EC6[System Alerts Owner/Manager] EC6 --> EC1 end ``` **Declaration Status Flow:** ``` created → en_attente_client → en_cours → termine → ferme → archive ↑ | └────────────────────┘ ``` **Key Interaction Details:** - **Bulk creation:** Select multiple clients from a filtered list → set shared type + deadline → create all at once - **Status auto-transitions:** Some status changes happen automatically while others require worker action (mark as termine/ferme) - **Nudge system:** Manager clicks nudge → worker gets notification with direct link to the declaration — no message composition, pure signal - **Activity log:** Every status change, reassignment, edit, upload, and nudge is logged with timestamp and actor — visible in declaration detail - **Deadline escalation:** System generates alerts as deadlines approach (7 days → amber, 3 days → red, overdue → critical alert to owner) ### Journey Patterns **Common patterns extracted across all journeys:** **Navigation Patterns:** - **KPI-to-List filtering:** Click summary card → filtered table (used in Owner, Manager, and Worker dashboards) - **Direct-link navigation:** Notifications, nudges, and alerts all deep-link directly to the relevant declaration — no hunting - **Breadcrumb context:** Dashboard → Client → Declaration — always know where you are and how to go back **Decision Patterns:** - **Inline actions:** Most decisions happen without leaving the list view (nudge, reassign, status change) - **Confirmation for destructive actions:** Reassignment and bulk operations show a confirmation step; simple status updates do not - **Progressive disclosure:** List view shows summary → click for detail → expand sections for full history **Feedback Patterns:** - **Toast notifications:** Quick actions (nudge sent, status updated) confirmed with non-blocking toast - **Real-time indicators:** New document uploads, status changes reflected with visual badges ("New", dot indicators) - **Deadline color gradient:** Green (>7 days) → Amber (3-7 days) → Red (<3 days) → Critical pulse (overdue) — consistent across all views ### Flow Optimization Principles 1. **Minimize clicks to value:** Dashboard → filtered list → action = 2 clicks maximum for any priority task 2. **No dead ends:** Every screen has a clear next action; error states include recovery paths 3. **Batch over individual:** Bulk creation, bulk notification, multi-select actions — respect the user's time when dealing with 45+ clients 4. **Context preservation:** Opening a declaration detail doesn't lose the list context — use slide-over panels or maintain scroll position on return 5. **Role-appropriate density:** Owners/Managers see the full picture; Workers see only their scope — same components, different data filters 6. **Zero-friction client portal:** Every additional field, button, or step on the client portal is a potential drop-off — keep it brutally simple ## Component Strategy ### Design System Components **shadcn-vue (reka-ui) — Installed (24 groups):** alert, avatar, badge, breadcrumb, button, card, checkbox, collapsible, dialog, dropdown-menu, input, input-otp, item, label, navigation-menu, select, separator, sheet, sidebar, skeleton, spinner, tabs, timeline, tooltip **shadcn-vue — Need to Install:** - **table** — Foundation for DataTable (sortable headers, row selection) - **calendar + popover** — Foundation for DateRangePicker - **combobox** — Searchable select for client/worker/type filtering - **toast / sonner** — Non-blocking feedback for quick actions (nudge sent, status updated) - **progress** — Upload progress bars (client portal) - **switch** — Toggle settings (compact mode, dark mode) - **command** — Command palette for power users (optional Phase 3) **Already Built Custom Components (30+):** AppShell, AppSidebar, AppHeader, NavMain, NavFooter, NavUser, WorkspaceSwitcher, NotificationDropdown, Pagination, Breadcrumbs, ClientForm, FolderForm, UserForm, WorkspaceForm, FolderCalendar, MessageBubble, TwoFactorSetupModal, TwoFactorRecoveryCodes, InputError, TextLink, Heading, UserInfo, AppearanceTabs, DeleteUser, PlaceholderPattern ### Custom Components **1. StatCard** - **Purpose:** Display KPI metrics on dashboards (overdue count, due this week, waiting for client, on track) - **Content:** Metric label, value (number), trend indicator (optional), status color - **Actions:** Clickable — filters the declaration list below when clicked - **States:** Default, active (selected as filter), loading (skeleton) - **Variants:** `status="danger|warning|info|success"` maps to deadline proximity colors - **Accessibility:** Role="button", aria-pressed for active state, keyboard focusable - **Implementation:** Compose from shadcn-vue `card` + CVA variants for status colors **2. DataTable** - **Purpose:** Primary data display for declarations, clients, and dossiers lists - **Content:** Sortable columns, row data, inline actions, selection checkboxes - **Actions:** Sort by column, select rows (single/multi), inline row actions (dropdown), click row to navigate - **States:** Default, loading (skeleton rows), empty (EmptyState), filtered (active filter indicators) - **Variants:** Default density (~48px rows), compact density (~36px rows, user preference) - **Accessibility:** Role="grid", aria-sort on headers, keyboard row navigation - **Implementation:** shadcn-vue `table` + TanStack Table v8 for sorting/filtering/selection logic **3. FilterBar** - **Purpose:** Persistent filter controls above all list views - **Content:** Search input, status filter (Combobox), date range (DateRangePicker), assignee filter (Combobox), type filter (Select) - **Actions:** Apply filters (instant, no submit button), clear all, save filter presets (Phase 3) - **States:** Default, active filters (count badge), collapsed on mobile (expandable) - **Variants:** Full (dashboard lists), minimal (portal views) - **Accessibility:** Role="search", aria-label for each filter, clear keyboard navigation between filters - **Implementation:** Composite of shadcn-vue `input` + `combobox` + `select` + custom `DateRangePicker` **4. DateRangePicker** - **Purpose:** Select date ranges for filtering declarations by deadline period - **Content:** Start date, end date, preset ranges (This week, This month, This quarter) - **Actions:** Select range via calendar, select preset, clear selection - **States:** Default (placeholder), selected (showing range), open (calendar visible) - **Accessibility:** Keyboard date navigation, aria-label for date inputs - **Implementation:** shadcn-vue `popover` + `calendar` (dual calendar view) **5. ActivityFeed** - **Purpose:** Real-time stream of workspace events on dashboard right panel - **Content:** Event type icon, actor name, action description, target link, timestamp - **Actions:** Click event to navigate to related entity, load more (infinite scroll) - **States:** Default, loading, empty - **Variants:** Dashboard panel (compact, last 20 events), full page (all events, filterable) - **Accessibility:** Role="feed", aria-label for each entry, keyboard navigation - **Implementation:** Custom component using existing `timeline` styling, Inertia polling or WebSocket for real-time **6. BulkActionBar** - **Purpose:** Contextual toolbar that appears when multiple table rows are selected - **Content:** Selected count, available actions (notify clients, reassign, change status, archive) - **Actions:** Execute bulk action with confirmation dialog - **States:** Hidden (no selection), visible (with selection count), processing (loading state during action) - **Accessibility:** Role="toolbar", announced via aria-live when appearing, keyboard operable - **Implementation:** Fixed bottom bar or sticky top bar, appears on row selection, uses existing `button` + `dropdown-menu` **7. StatusBadge** - **Purpose:** Visual indicator for declaration status throughout the app - **Content:** Status label text, optional icon - **States/Variants:** Maps to declaration lifecycle — created (gray), en_attente_client (blue), en_cours (amber), termine (green), ferme (teal), archive (muted), overdue (red pulsing) - **Accessibility:** Status text readable by screen readers, color not sole indicator (icon + text) - **Implementation:** Extend existing `badge` with CVA status variants using OKLCH semantic tokens **8. FileUploadZone** - **Purpose:** Document upload area for client portal and internal document management - **Content:** Drop zone area, file type/size constraints, upload progress, uploaded files list - **Actions:** Drag & drop, click to browse, remove uploaded file, retry failed upload - **States:** Default (empty), drag-over (highlighted), uploading (progress), success (file listed), error (retry option) - **Variants:** Portal (large, single-purpose), inline (compact, within declaration detail) - **Accessibility:** Role="button" for click-to-browse, keyboard operable, progress announced via aria-live - **Implementation:** Custom component with native drag-and-drop API, chunked upload for large files **9. EmptyState** - **Purpose:** Placeholder for lists/pages with no data, guiding users toward action - **Content:** Illustration (optional), title, description, primary action button - **Variants:** Table empty (inline), page empty (centered), first-time (onboarding-oriented) - **Accessibility:** Descriptive text, action button focusable - **Implementation:** Simple layout component with slots for icon, text, and action **10. DeclarationStatusStepper** - **Purpose:** Visual progress indicator showing where a declaration is in its lifecycle - **Content:** All status steps with current step highlighted, timestamps for completed steps - **States:** Each step can be: completed, current, upcoming, or skipped - **Accessibility:** Role="progressbar" or ordered list with aria-current - **Implementation:** Horizontal stepper using existing `timeline` tokens, shown in declaration detail view ### Component Implementation Strategy **Design Token Integration:** - All custom components use OKLCH color tokens from `app.css` — no hardcoded colors - CVA (Class Variance Authority) for all component variants — consistent with shadcn-vue patterns - Tailwind CSS 4 utility classes for layout and spacing — no custom CSS unless necessary - Dark mode support via existing `dark:` variants in all new components **Composition Pattern:** - Custom components are composed from shadcn-vue primitives where possible (StatCard wraps Card, StatusBadge extends Badge, FilterBar combines Input + Combobox + Select) - Reuse reka-ui accessibility primitives (focus management, keyboard navigation, ARIA attributes) - TypeScript strict mode with proper prop typing and emits **State Management:** - Component state managed locally (Vue 3 Composition API `ref`/`computed`) - Server state via Inertia.js props — no client-side data fetching library needed - Shared UI state (sidebar collapsed, compact mode) via composables or Pinia store ### Implementation Roadmap **Phase 1 — Core (MVP Dashboard & Lists):** - Install: `table`, `combobox`, `toast/sonner`, `calendar`, `popover`, `progress` - Build: StatCard, DataTable, FilterBar, StatusBadge, EmptyState, BulkActionBar - These components are required for Journey 1 (Dashboard) and Journey 2 (Worker Workflow) **Phase 2 — Client Portal & Communication:** - Build: FileUploadZone, DeclarationStatusStepper - Enhance: ActivityFeed, DateRangePicker - These components are required for Journey 3 (Client Upload) and Journey 4 (Declaration Lifecycle) **Phase 3 — Power Features & Polish:** - Install: `command` (command palette), `switch` - Build: SavedFilterPresets, KeyboardShortcutHelper, CompactModeToggle - Enhance: DataTable (column resizing, pinned columns), FilterBar (saved presets) - These components optimize efficiency for power users processing high volumes ## UX Consistency Patterns ### Button Hierarchy **Primary Action (one per screen section):** - Solid fill with primary color (`bg-primary text-primary-foreground`) - Used for: Create declaration, Save changes, Submit, Send notification - Always positioned bottom-right of forms, or top-right of page headers for creation actions **Secondary Action:** - Outline variant (`border border-input bg-background`) - Used for: Cancel, Back, Export, secondary options alongside a primary - Positioned left of primary action in button groups **Destructive Action:** - Destructive variant (`bg-destructive text-destructive-foreground`) - Used for: Delete, Archive (with confirmation), Remove team member - Always requires confirmation dialog — never immediate **Ghost/Inline Action:** - Ghost variant (no border, no background, text only) - Used for: Inline table row actions, "View all" links, tertiary options - Appears on hover in table rows via dropdown-menu trigger **Icon-Only Action:** - Icon button with tooltip (mandatory for accessibility) - Used for: Nudge (bell icon), Refresh, Toggle sidebar, Quick actions - Always paired with `tooltip` for label — never icon-only without tooltip **Button Sizing:** - Default size for all primary UI actions - `size="sm"` only inside table rows and compact toolbars - `size="lg"` only for client portal CTA buttons (mobile touch targets) ### Feedback Patterns **Toast Notifications (non-blocking):** - **Success:** Green check icon + message — auto-dismiss after 4 seconds - Used for: Status updated, Nudge sent, Declaration created, Document uploaded - **Error:** Red X icon + message — persists until dismissed - Used for: Save failed, Upload failed, Permission denied - **Info:** Blue info icon + message — auto-dismiss after 5 seconds - Used for: New document received, Declaration reassigned to you - **Warning:** Amber warning icon + message — persists until dismissed - Used for: Deadline approaching, Bulk action affects X items - Position: Top-right, stacked, max 3 visible at once **Inline Validation (forms):** - Real-time validation on blur (not on keystroke) - Error text appears below the field in `text-destructive` with shake animation - Success state: Green check icon inside the input (not below) - Server-side errors (from Laravel Form Request) displayed inline on the relevant field via Inertia error bags **Confirmation Dialogs:** - Required for: Delete, Archive, Bulk actions, Reassignment - Not required for: Status updates, Nudges, Single notifications - Dialog content: Clear description of what will happen, affected item count for bulk actions - Two buttons: Cancel (secondary, left) + Confirm (primary or destructive, right) - Destructive confirmations use red confirm button with action verb ("Delete 5 declarations" not "OK") **Loading States:** - **Initial page load:** Skeleton screens matching the layout structure (StatCard skeletons, table row skeletons) - **Action processing:** Button shows spinner + disabled state, label changes to "Saving..." / "Sending..." - **Table refresh:** Subtle opacity reduction (0.6) on table body while loading, no full skeleton replacement - **File upload:** Progress bar with percentage inside FileUploadZone **Empty States:** - Every list/table has a designed empty state via `EmptyState` component - Includes: Relevant illustration/icon, explanatory text, primary action button - Examples: "No declarations yet — Create your first declaration", "No overdue items — You're on track!" ### Form Patterns **Form Layout:** - Single-column layout for all forms (max-width 640px centered) - Labels above inputs (not inline/floating) — better for scanning and accessibility - Required fields: No asterisk — all fields required by default; mark optional fields with "(optional)" suffix - Field grouping: Use `separator` + section headings for logical groups (Client Info, Declaration Details, etc.) **Input Patterns:** - Text inputs: shadcn-vue `input` with `label` above - Select/dropdown: shadcn-vue `select` for short lists (<10 items), `combobox` for searchable lists (>10 items) - Date selection: `DateRangePicker` for ranges, single `calendar` popover for individual dates - File upload: `FileUploadZone` component — drag-and-drop + click-to-browse **Form Submission:** - Inertia.js `useForm()` for all form handling — provides processing state, errors, and recentlySuccessful - Submit button disables during processing with spinner - On success: Toast notification + redirect (for create) or toast + stay on page (for edit) - On error: Scroll to first error field, focus it, display inline error messages **Inline Editing:** - Status changes on declarations: Inline dropdown, no modal, immediate save - Quick edits: Click to edit pattern only for simple fields (declaration type, deadline date) - Complex edits: Always navigate to edit form (client details, user profiles) ### Navigation Patterns **Sidebar Navigation:** - Full sidebar (240px) with grouped sections: Dashboard, Clients, Declarations, Archive, Team, Settings - Active section highlighted with primary color background - Collapsible groups for sub-items (e.g., Settings → Profile, Team, Workspace, Appearance) - Collapse to icon-only (64px) on smaller screens, overlay drawer on mobile (<768px) - WorkspaceSwitcher at the top of sidebar **Breadcrumbs:** - Always visible below the page header: Dashboard / Clients / Client Name / Declaration - Last item is the current page (non-clickable, muted text) - All previous items are clickable links - Mobile: Show only current + parent (collapse middle items with "...") **Page Headers:** - Every page has a consistent header: Page title (h1) + description (optional) + primary action button (top-right) - Examples: "Declarations" + "Create Declaration" button, "Client: Benani SARL" + "Edit" button **Back Navigation:** - Browser back button works correctly (Inertia.js handles history) - No explicit "Back" buttons in the UI — breadcrumbs serve this purpose - Modals/sheets close with Escape key and clicking outside **Deep Linking:** - Every notification, nudge, and alert links directly to the relevant entity - URL structure reflects navigation hierarchy: `/clients/123/declarations/456` - Sharing a URL always works — no client-side routing state that breaks on refresh ### Additional Patterns **Table Interaction Patterns:** - **Row hover:** Subtle background highlight + inline action icons appear (right side) - **Row click:** Navigates to detail page (entire row is clickable except action buttons) - **Sort:** Click column header to sort — ascending → descending → unsorted. Active sort shown with arrow icon - **Selection:** Checkbox column (first column) for multi-select. Header checkbox toggles all visible rows - **Pagination:** Bottom of table — "Showing 1-25 of 142" + page navigation. Default 25 rows per page, configurable (25/50/100) - **Sticky header:** Table header sticks when scrolling long lists **Search & Filter Patterns:** - **FilterBar** always visible above data tables (not hidden behind a toggle) - Filters apply instantly on change (no "Apply" button needed) - Active filters shown as removable chips/badges below the filter bar - "Clear all filters" link when any filter is active - URL query parameters reflect filter state — shareable filtered views **Date & Time Patterns:** - Dates displayed in Moroccan format: DD/MM/YYYY - Relative time for recent events: "il y a 2 heures", "hier" - Deadlines always show absolute date + relative countdown: "20/03/2026 (dans 5 jours)" - Deadline color coding consistent everywhere: Green (>7d), Amber (3-7d), Red (<3d), Pulsing red (overdue) **Notification Patterns:** - **In-app:** Badge count on sidebar bell icon, dropdown panel with recent notifications, mark as read - **Email:** Triggered by: client document requests, nudges (configurable), deadline warnings (configurable) - **Notification grouping:** Multiple events for same entity grouped ("3 clients uploaded documents") - **Quiet hours:** No email notifications outside business hours (configurable per workspace) **Error & Recovery Patterns:** - **Network error:** Toast with "Connection lost — changes will sync when reconnected" (Inertia handles gracefully) - **Permission denied:** Redirect to dashboard with toast "You don't have permission to access this page" - **404 Not Found:** Custom error page with "Go to Dashboard" link - **Server error (500):** Custom error page with "Try again" + "Contact support" options - **Session expired:** Redirect to login with "Your session expired — please log in again" message, preserving intended destination URL ## Responsive Design & Accessibility ### Responsive Strategy **Desktop (Primary — Firm Staff):** - Full "Command Professional" layout: 240px sidebar + main content area - Two-column dashboard: KPI cards + table left, activity feed + alerts right - Data tables at full width with all columns visible - Inline row actions on hover, keyboard shortcuts for power users - Multi-panel views where appropriate (e.g., declaration detail with document preview sidebar) **Tablet (Secondary — Firm Staff on the Go):** - Sidebar collapses to icon-only (64px) by default, expandable on tap - Dashboard KPI cards reflow to 2-column grid - Activity feed moves below the main table (single column) - Tables maintain core columns, hide secondary columns behind a "More" expandable - Touch-optimized: Larger tap targets on action buttons, swipe gestures for table row actions (optional) **Mobile (Primary — Client Portal / Secondary — Firm Staff):** - **Client portal:** Single-column, mobile-first layout — this is the primary device for Hassan-type users - **Firm app:** Sidebar becomes overlay drawer (hamburger trigger in top-left) - KPI cards stack single-column, full width - Tables transform to card-based list view — each row becomes a card showing key fields - Bottom sheet for actions instead of dropdown menus (better mobile UX) - Large touch targets: minimum 44x44px for all interactive elements - Camera integration for document upload (direct photo capture) **Device Priority Matrix:** | User Role | Primary Device | Secondary Device | |---|---|---| | Owner (Karim) | Desktop | Tablet/Mobile (checking dashboard) | | Manager (Rachid) | Desktop | Mobile (nudges, quick reassignment) | | Worker (Fatima) | Desktop | Rarely mobile | | Client (Hassan) | **Mobile** | Desktop | | Admin (Saad) | Desktop | — | ### Breakpoint Strategy **Tailwind CSS 4 Breakpoints (standard):** | Breakpoint | Width | Layout Behavior | |---|---|---| | `sm` | 640px+ | Client portal: content max-width, centered | | `md` | 768px+ | Sidebar visible (icon-only), tables show core columns | | `lg` | 1024px+ | Sidebar expanded (240px), full table columns, two-column dashboard | | `xl` | 1280px+ | Extra breathing room, wider tables, optional third column | | `2xl` | 1536px+ | Max content width (1400px centered), prevent ultra-wide line lengths | **Mobile-First Approach:** - Base styles target mobile (< 640px) - Progressive enhancement via `sm:`, `md:`, `lg:` prefixes - Client portal designed mobile-first — desktop is the enhanced version - Firm app designed desktop-first conceptually, but implemented mobile-first in code **Key Responsive Behaviors:** | Component | Mobile (<768px) | Tablet (768-1023px) | Desktop (1024px+) | |---|---|---|---| | Sidebar | Overlay drawer | Icon-only (64px) | Full (240px) | | KPI Cards | 1 column stack | 2 column grid | 4 column grid (auto-fill) | | DataTable | Card list view | Table with fewer columns | Full table with all columns | | FilterBar | Collapsed (expandable toggle) | Single row, scrollable | Full row, all filters visible | | BulkActionBar | Fixed bottom sheet | Fixed bottom bar | Sticky top bar | | Activity Feed | Hidden (accessible via tab) | Below main content | Right sidebar panel | | Modals/Dialogs | Full-screen sheet (bottom-up) | Centered dialog | Centered dialog | ### Accessibility Strategy **Target Compliance: WCAG 2.1 Level AA** - This is the industry standard and appropriate for a B2B SaaS product - Level AAA is not targeted but specific AAA criteria will be met where practical (e.g., enhanced contrast) - Morocco does not have specific web accessibility legislation, but AA compliance ensures usability for all users and future-proofs against potential regulation **Color & Contrast:** - Minimum 4.5:1 contrast ratio for normal text (< 18px) - Minimum 3:1 contrast ratio for large text (>= 18px bold or >= 24px) - OKLCH color tokens already tested for contrast compliance in light and dark modes - Color is never the sole indicator of status — always paired with icon and/or text label - Deadline color gradient (green → amber → red) supplemented by text labels ("On track", "Due soon", "Overdue") **Keyboard Navigation:** - All interactive elements reachable via Tab key - Logical tab order following visual layout (left-to-right, top-to-bottom) - Skip-to-content link as first focusable element on every page - Visible focus indicators: 2px ring using `ring-ring` token (already configured in shadcn-vue) - Escape key closes modals, sheets, dropdowns, and popovers - Table keyboard navigation: Arrow keys for row/cell navigation within DataTable - Custom keyboard shortcuts documented and discoverable (Phase 3) **Screen Reader Support:** - Semantic HTML5 elements: `