Design: Budget Lines Management (BUDMGT)¶
Brand: BOTH (Papillon HR Suite + ALTARYS ENTERPRISE HR Suite) Date: 10/03/2026 Version: 1.0 Author: DESIGNER (Claude — Senior UX/UI Designer) PRD Source: docs/prd/budget-lines-management-prd.md v1.0 Architecture Source: docs/architecture/budget-lines-management-arch.md
For the DEVELOPER: This is your single source of truth for all UI/UX implementation in the Budget Lines Management module. Every screen, interaction, state, and micro-copy is specified here. When the PRD says what to build and the architecture says how to build it, this document says what it looks and feels like. Follow this document exactly. If something is ambiguous, check the PRD — if still ambiguous, ask the DESIGNER.
Key rules: - Papillon brand = warm amber, mobile-first, generous whitespace, guided - Enterprise brand = navy, desktop-first, dense, power-user - All amounts: XOF, zero decimals, space as thousands separator (e.g.
15 000 000 XOF) - All dates: DD/MM/YYYY - All UI text in French (see §11 Micro-copy) - Offline: read-only cache with staleness banner. All mutations are online-only (FR-PV-062) - Touch targets: minimum 48×48px on mobile
Table of Contents¶
- Scope & Screens Index
- Design Decisions Log
- User Flow Diagrams
- Screen Specifications
- 4.1 Budget Setup Wizard (First-Time)
- 4.2 Dashboard Tab — Tableau de bord
- 4.3 Budget Lines Tab — Lignes budgétaires
- 4.4 Budget Line Detail
- 4.5 Transfers Tab — Virements
- 4.6 Transfer Creation
- 4.7 Transfer Approval (DG/Finance Director)
- 4.8 Budget Settings
- 4.9 Manager View (Department-Scoped)
- 4.10 Budget Validation Ceremony
- 4.11 Year-End Closure Flow
- 4.12 Over-Budget Override Request
- Responsive Behavior
- Offline Behavior
- Motion Choreography
- Loading, Empty, Error & Success States
- Component Specifications
- Enterprise Brand Divergence
- French Micro-copy
- Brand Compliance Checklist
1. Scope & Screens Index¶
Personas Served¶
| Persona | Access Level | Primary Screens |
|---|---|---|
| DG (P1) | Full — create, validate, approve, close | All screens + validation ceremony + year-end closure |
| Comptable (P3) | Create, edit, transfer, export | All screens except validation (can trigger closure if delegated) |
| Finance Director (P3b) | Approve transfers, approve overrides, view all | Dashboard, lines, transfers (approval), settings (read) |
| Manager (N+1) | Read-only, department-scoped | Manager view (filtered dashboard + lines) |
| Employé (P4) | No access | — |
Screen Map¶
| # | Screen | Route | Access | PRD Reference |
|---|---|---|---|---|
| S1 | Budget Setup Wizard | /budget/setup |
Comptable, DG | US-BUD-001, US-BUD-009 |
| S2 | Dashboard Tab | /budget (default) |
All with access | US-BUD-006 |
| S3 | Budget Lines Tab | /budget/lines |
All with access | US-BUD-003 |
| S4 | Budget Line Detail | /budget/lines/:id |
All with access | US-BUD-003, US-BUD-005 |
| S5 | Transfers Tab | /budget/transfers |
Comptable, DG, P3b | US-BUD-004 |
| S6 | Transfer Creation | /budget/transfers/new |
Comptable, DG | US-BUD-004 |
| S7 | Transfer Approval | /budget/transfers/:id |
DG, P3b | US-BUD-004 |
| S8 | Budget Settings | /budget/settings |
Comptable, DG | US-BUD-005 |
| S9 | Manager View | /budget (auto-routed) |
Manager | US-BUD-007 |
| S10 | Budget Validation | /budget/validate (modal overlay) |
DG only | US-BUD-002 |
| S11 | Year-End Closure | /budget/close (modal overlay) |
DG, Comptable | FR-BUD-060–064 |
| S12 | Over-Budget Override | notification deep-link | DG, P3b | FR-BUD-035 |
2. Design Decisions Log¶
Every key UX decision is logged here with rationale, so this document doubles as a learning reference.
| # | Decision | Choice | Rationale |
|---|---|---|---|
| DD-01 | Module navigation structure | 3-tab bar within module: Tableau de bord | Lignes | Virements | 3 tabs = optimal for Hick's Law (fast scan). All areas visible at once. Comptable switches between tabs constantly — one tap always. No hidden sections. |
| DD-02 | First-time budget wizard depth | 3-step minimal: (1) Name + fiscal year, (2) Add budget lines, (3) Review & confirm | Progressive disclosure: get users productive in <2 min. Thresholds ship with smart defaults (80/95/100%). Tip at end points to Settings for customization. Avoids "government form" anxiety. |
| DD-03 | Dashboard visualization | 4 large KPI cards + stacked horizontal bar + per-category mini bars | Shneiderman's mantra: "overview first, details on demand." 4 KPIs serve the Comptable (breakdown needed). Stacked bar serves the DG (one-glance health check). Category bars enable drill-down without leaving the page. |
| DD-04 | Budget lines display | Cards grouped by category (mobile) / Hybrid cards+table (desktop) | Cards are touch-friendly and scannable on mobile. Category grouping matches the Comptable's mental model (they think in SYSCOHADA categories). Desktop gets a data table for power sorting/filtering. Progressive disclosure: card shows label + bar + available; tap to expand full breakdown. |
| DD-05 | Transfer creation pattern | Visual "from → to" metaphor with source on top, amount in middle, destination on bottom | Don Norman's "mapping" principle: the UI literally looks like money flowing from A to B. Real-time preview shows balance impact before submission. More intuitive than a flat form for users who think of transfers as "moving money." |
| DD-06 | Transfer/override approval UX | Swipe cards on mobile, inline buttons on desktop | Fitts's Law: swipe is the fastest gesture for binary decisions on touch. Familiar from M-Pesa/mobile banking in the region. Desktop uses explicit buttons (no hover-dependent swipe). Rejection always requires a reason (bottom sheet). |
| DD-07 | Manager view | Same layout as full view but filtered + read-only badge | Consistency: managers see the same UI patterns they'd see if promoted to DG. "Lecture seule" badge makes the read-only constraint visible, not hidden. Department filter is automatic, not user-selectable. |
| DD-08 | Threshold visualization | Color-coded progress bars on each budget line card | Color is NOT the only indicator (paired with % text and icon). Green (<80%), Amber (80-95%), Red (>95%). The bar itself tells the story — no need to read numbers for a quick health check. |
| DD-09 | Budget validation | Celebration moment: confetti + status badge animation | Validates the DG's authority. This is a milestone action (happens once per year). The celebration reinforces that something important just happened. Not a silent state change — a signature moment. |
| DD-10 | Year-end closure | Two-step confirmation with open commitment warning | Irreversible action requires friction. Step 1: Summary of open commitments. Step 2: Explicit "Je confirme la clôture" text acknowledgment. Not a simple "Are you sure?" dialog — the user must understand what they're closing. |
| DD-11 | Offline behavior | Read-only cache + staleness banner + mutations blocked with clear message | Per FR-PV-062: financial mutations require connectivity. Offline users see cached data with a warm-toned banner (not alarming red). All action buttons are disabled with explanatory tooltips. |
| DD-12 | Empty state (first-time) | Guided illustration + single CTA to wizard | First-time users see a warm illustration (not a blank screen) with "Créez votre premier budget" CTA. The illustration maps to their mental model — e.g., a paper budget being transformed into a digital one. |
3. User Flow Diagrams¶
3.1 First Budget Creation Flow¶
flowchart TD
A[User opens BUDMGT<br/>for first time] --> B{Budget exists<br/>for current FY?}
B -->|No| C[Show Empty State<br/>'Créez votre premier budget']
B -->|Yes| D[Show Dashboard Tab]
C --> E[Tap 'Créer mon budget']
E --> F[Wizard Step 1:<br/>Name + Fiscal Year]
F --> G[Wizard Step 2:<br/>Add Budget Lines]
G --> H{At least 1 line<br/>added?}
H -->|No| I[Validation message:<br/>'Ajoutez au moins une ligne']
I --> G
H -->|Yes| J[Wizard Step 3:<br/>Review & Confirm]
J --> K[Tap 'Créer le budget']
K --> L[Budget created<br/>in DRAFT status]
L --> M[Success animation +<br/>redirect to Dashboard]
M --> N[Tooltip: 'Le DG peut<br/>valider ce budget']
3.2 Budget Lifecycle Flow (DG)¶
flowchart TD
A[Budget in DRAFT] --> B[DG reviews budget lines]
B --> C[DG taps 'Valider le budget']
C --> D[Validation Ceremony:<br/>Summary + Confirm]
D --> E{DG confirms?}
E -->|Yes| F[Budget → ACTIVE<br/>🎊 Confetti animation]
E -->|Cancel| A
F --> G[Normal operations:<br/>reserves, consumes, releases,<br/>transfers]
G --> H[Fiscal year ends]
H --> I[System prompts:<br/>'Clôturer le budget ?']
I --> J[Year-End Closure Flow]
J --> K{Open commitments?}
K -->|Yes| L[Warning: N lignes<br/>avec engagements]
K -->|No| M[Confirmation step]
L --> M
M --> N{DG confirms?}
N -->|Yes| O[Budget → CLOSED<br/>Read-only archive]
N -->|Cancel| G
3.3 Budget Transfer Flow¶
flowchart TD
A[Comptable opens<br/>Virements tab] --> B[Tap '+ Nouveau virement']
B --> C[Transfer Creation screen:<br/>Source / Amount / Destination]
C --> D[Select source line]
D --> E[Enter amount]
E --> F{Amount > source<br/>available?}
F -->|Yes| G[Inline error:<br/>'Montant insuffisant']
G --> E
F -->|No| H[Select destination line]
H --> I[Enter justification]
I --> J[Tap 'Soumettre']
J --> K{DG is requester?}
K -->|Yes| L[Auto-approved<br/>SELF_APPROVED]
K -->|No| M[Transfer → PENDING<br/>Notification to DG/P3b]
M --> N[DG/P3b opens<br/>approval card]
N --> O{Decision?}
O -->|Approve swipe/tap| P[Transfer → APPROVED<br/>Allocations updated atomically]
O -->|Reject swipe/tap| Q[Bottom sheet:<br/>Enter rejection reason]
Q --> R[Transfer → REJECTED<br/>Notification to requester]
L --> S[Success: allocations<br/>updated immediately]
3.4 Budget Availability Check (System-Initiated)¶
flowchart TD
A[COMMIT/EXPMGT event:<br/>CommitmentApproved or<br/>ExpenseApproved] --> B[BUDMGT checks<br/>budget line balance]
B --> C{Consumption vs<br/>thresholds?}
C -->|Below warn| D[✅ Allow<br/>Reserve/Consume silently]
C -->|≥ Warn threshold| E[✅ Allow<br/>Send notification<br/>to Comptable + DG]
C -->|≥ Alert threshold| F[✅ Allow<br/>Send urgent notification<br/>+ email]
C -->|≥ Action threshold| G{Enforcement<br/>level?}
G -->|WARN| H[✅ Allow<br/>Log over-budget<br/>Visual warning on line]
G -->|REQUIRE_OVERRIDE| I[⏸️ Block<br/>Override request created<br/>Notification to DG/P3b]
G -->|HARD_BLOCK| J[❌ Block<br/>Operation rejected<br/>Error to user]
I --> K[DG/P3b reviews<br/>override request]
K --> L{Decision?}
L -->|Approve| M[Operation proceeds<br/>Budget mutated]
L -->|Reject| N[Original commitment/<br/>expense rejected]
3.5 Offline Flow¶
flowchart TD
A[User opens BUDMGT] --> B{Online?}
B -->|Yes| C[Fetch fresh data<br/>Update IndexedDB cache]
C --> D[Show live dashboard<br/>All actions enabled]
B -->|No| E{Cache exists?}
E -->|Yes| F[Show cached data<br/>+ staleness banner]
F --> G[All mutation buttons<br/>disabled with tooltip]
E -->|No| H[Show offline<br/>empty state]
D --> I{Connection lost<br/>during session?}
I -->|Yes| J[Show transition banner:<br/>'Connexion perdue']
J --> G
G --> K{Connection restored?}
K -->|Yes| L[Auto-refresh data<br/>Remove banner<br/>Enable buttons]
4. Screen Specifications¶
4.1 Budget Setup Wizard (First-Time)¶
Design decisions applied: DD-02 (3-step minimal), DD-12 (guided empty state)
Entry Point: Empty State¶
When no budget exists for the current fiscal year, users see a warm empty state instead of the module tabs.
Layout (mobile 360px): - Full-screen centered content - Warm illustration at top (paper budget transforming into digital sparkle — evokes the paper→digital transition) - Headline: "Créez votre premier budget" - Subtext: "En quelques minutes, donnez-vous une vision claire de vos dépenses." - Single primary CTA button: "Commencer" - Background: Warm gradient (amber-tinted cream → white, Papillon) / Clean white (Enterprise)
Layout (desktop 1440px): - Split layout: illustration on left (40%), text + CTA on right (60%) - Same content, more breathing room
Step 1 of 3: Paramètres¶
Components: - Progress indicator: 3 dots with step labels, current step highlighted in primary color - Step title: "Paramètres du budget" - Form fields: - Nom du budget: Text input, pre-filled with "Budget {current_year}" (e.g., "Budget 2026"). Editable. - Exercice fiscal: Read-only display showing tenant's configured fiscal year dates (e.g., "01/01/2026 — 31/12/2026"). If mid-year, shows option to set custom start date. - Date de début effective (conditional): Date picker, shown only if mid-year creation detected. Default: today's date. Label: "Votre budget démarrera à partir de cette date." - Navigation: "Suivant →" button (primary, bottom-right)
Validation: - Nom: required, max 100 chars - Date de début: must be within current fiscal year
Auto-fill logic: Fiscal year dates fetched from Control Plane tenant config. If tenant hasn't configured fiscal year, default to Jan 1 – Dec 31 of current year.
Step 2 of 3: Lignes budgétaires¶
Components: - Step title: "Ajoutez vos lignes budgétaires" - Contextual hint (first time only, dismissible): "💡 Commencez par les postes de dépenses les plus importants. Vous pourrez en ajouter d'autres plus tard." - Budget lines list: Empty initially. Each added line shows as a card: - Category badge (color-coded) - Label - Allocation amount - Edit (pencil icon) / Remove (trash icon) actions - "+ Ajouter une ligne" button: Opens an inline form (slides down from button, not a modal — keeps context visible): - Category: Select dropdown, grouped by pre-seeded categories. Option to "Créer une catégorie" at bottom of list. - Label: Text input (e.g., "Salaires mensuels") - Montant alloué (XOF): Number input with thousands formatting as user types. Enforces whole numbers. - Service (optionnel): Select dropdown of org units from Control Plane. "Toute l'entreprise" default. - Compte SYSCOHADA (optionnel): Searchable dropdown. Prompt: "Souhaitez-vous associer un compte SYSCOHADA ?" with skip link. - "Ajouter" button (primary) + "Annuler" link - Running total: Sticky bar at bottom showing "Total : {sum} XOF" — updates live as lines are added. - Navigation: "← Retour" (ghost button) + "Suivant →" (primary)
Validation: - At least 1 budget line required to proceed - Each line: label required, allocation ≥ 0, allocation must be whole number
Mobile behavior: Inline form pushes content down (accordion-style). On small screens, the form takes full width.
Desktop behavior: Lines display in a compact list/table format. Inline form appears above the list.
Step 3 of 3: Récapitulatif¶
Components: - Step title: "Récapitulatif" - Summary card: - Budget name + fiscal year - Effective start date (if mid-year) - Total allocation (large, prominent) - Number of budget lines - Budget lines grouped by category, each showing: label + allocation - Info callout (warm tone): "Ce budget sera créé en mode brouillon. Le Directeur Général pourra le valider pour le rendre officiel." - Tip callout: "💡 Astuce : vous pouvez configurer des seuils d'alerte dans Paramètres > Seuils après la création." - Navigation: "← Retour" + "Créer le budget" (primary CTA)
Success behavior: - On tap "Créer le budget": 1. Button shows loading spinner (inline, not full-page) 2. Budget created via API 3. Success animation: Card scales up slightly with a subtle sparkle/glow effect 4. Redirect to Dashboard Tab after 1.5s 5. If user is DG: show tooltip on "Valider le budget" action pointing to the validate button
4.2 Dashboard Tab — Tableau de bord¶
Design decisions applied: DD-01 (tab navigation), DD-03 (4 KPIs + bar)
This is the default landing screen for the budget module.
Module Header¶
Components:
- Budget name + status badge: "Budget 2026" + BROUILLON / ACTIF / CLÔTURÉ
- BROUILLON: Amber/gold badge
- ACTIF: Green badge
- CLÔTURÉ: Grey badge
- Fiscal year selector (if multiple budgets exist): Dropdown to switch between current ACTIVE and next DRAFT
- Sync status indicator: Green dot (synced) / Orange dot (pending) / Pulsing (syncing)
- Action menu (⋮): "Paramètres", "Exporter", "Valider le budget" (DG only, DRAFT only), "Clôturer" (ACTIVE only)
Tab Bar¶
3 tabs, horizontally aligned below header: - Tableau de bord (active by default) — icon: 📊 - Lignes budgétaires — icon: 📋 - Virements — icon: ↔️ + badge count for pending (if approver)
Mobile: Tabs take full width, text may truncate to "Tableau" / "Lignes" / "Virem." with icons always visible. Scrollable if needed.
Desktop: Full labels, no truncation. Tabs left-aligned with generous padding.
KPI Cards Section¶
4 cards in a 2×2 grid (mobile) / 4-column row (desktop):
| Card | Label | Value Format | Color Accent |
|---|---|---|---|
| 1 | Allocation totale | 25 000 000 XOF |
Primary (amber/Papillon, navy/Enterprise) |
| 2 | Engagé | 8 000 000 XOF |
Teal |
| 3 | Réalisé | 12 000 000 XOF |
Deep amber |
| 4 | Disponible | 5 000 000 XOF |
Green (if healthy) / Red (if <10% of allocation) |
Each card: - Large amount (display font, 24px mobile / 32px desktop) - Label below (body font, 14px, muted) - Subtle background tint matching the accent color (5-10% opacity) - Entrance animation: Stagger 60ms per card, slide-up + fade-in
Consumption Bar¶
Below KPI cards. Full-width horizontal stacked bar: - Segment 1 (teal): Engagé proportion - Segment 2 (deep amber): Réalisé proportion - Segment 3 (light green): Disponible proportion - Percentage label above bar: "68% consommé" - Legend below bar: colored dots + labels
Bar height: 12px (mobile) / 16px (desktop). Rounded corners. Animation: Bar fills from left on entrance, 600ms ease-out.
Category Breakdown¶
Section header: "Par catégorie"
List of categories, each showing: - Category name (bold) - Mini progress bar (same color coding as main bar) - Consumption percentage - Tappable: navigates to Lines tab filtered by this category
Desktop enhancement: Category breakdown displayed as a horizontal bar chart alongside the main consumption bar, in a 2-column layout (bar chart left 60%, category list right 40%).
Department Breakdown (if department-scoped lines exist)¶
Section header: "Par service"
Same layout as category breakdown, but grouped by org unit.
Only shown if at least one budget line has org_unit_id set.
Export Button¶
Floating action position (mobile: bottom-right FAB) / inline button (desktop: top-right, next to header): - Label: "Exporter" - Options: "Excel (.xlsx)" / "CSV (.csv)" - Triggers download of budget vs. actual data
4.3 Budget Lines Tab — Lignes budgétaires¶
Design decisions applied: DD-04 (cards grouped by category), DD-08 (color-coded progress bars)
Mobile Layout (360px) — Card-Based¶
Search + Filter Bar: - Search input: "Rechercher une ligne…" (searches label and category) - Filter chips: "Toutes" (default) | category filters (scrollable horizontal chips) - Sort: Hidden behind sort icon. Options: "Par catégorie" (default), "Par consommation ↓", "Par disponible ↑", "Alphabétique"
Budget Lines List:
Lines are grouped by category. Each group: - Category header: Category name + line count + total allocation for category - Collapsible: ▼ (expanded) / ▶ (collapsed). Default: all expanded. - Budget line cards within the group:
┌─────────────────────────────────┐
│ Salaires mensuels 72% │
│ ████████████░░░ │
│ Disponible: 1 400 000 XOF │
│ Service: │
│ Compta │
└─────────────────────────────────┘
Each card shows: - Label (bold, left) + Consumption % (right, colored: green/amber/red per DD-08) - Progress bar: Full width, colored by threshold zone - Green fill: consumption < 80% (warn threshold) - Amber fill: 80% ≤ consumption < 95% - Red fill: consumption ≥ 95% - If enforcement is HARD_BLOCK or REQUIRE_OVERRIDE: small shield icon on the bar - Available amount: "Disponible: {amount} XOF" (the most actionable number) - Department badge (if department-scoped): Small pill showing department name - Tap action: Navigate to Budget Line Detail (S4)
Add Line Button (DRAFT budget only): - Sticky bottom bar: "+ Ajouter une ligne" (full-width primary button) - Not shown if budget is ACTIVE or CLOSED
Desktop Layout (1440px) — Data Table¶
Toolbar: - Search input (wider) - Category filter dropdown (multi-select) - Department filter dropdown - Sort dropdowns - View toggle: "Cartes" / "Tableau" (default: Tableau on desktop) - "+ Ajouter une ligne" button (DRAFT only)
Table columns:
| Column | Width | Sortable | Notes |
|---|---|---|---|
| Ligne | 25% | Yes | Label + department badge |
| Catégorie | 15% | Yes | Category name |
| Allocation | 15% | Yes | Formatted amount |
| Engagé | 10% | Yes | Formatted amount |
| Réalisé | 10% | Yes | Formatted amount |
| Disponible | 15% | Yes | Formatted amount + color |
| Consommation | 10% | Yes | % + mini progress bar |
Table rows: - Grouped by category (collapsible groups) or flat (user toggle) - Row hover: Slight elevation increase + pointer cursor - Row click: Navigate to Budget Line Detail - Category group header row: Bold, slightly different background tint, shows category total
Keyboard shortcuts (Enterprise):
- ↑/↓: Navigate rows
- Enter: Open selected line detail
- n: New line (if DRAFT)
- /: Focus search
- e: Export
4.4 Budget Line Detail¶
Design decisions applied: DD-08 (threshold visualization)
Full-screen view for a single budget line. Reached by tapping a card or table row.
Header¶
- Back navigation: "← Lignes budgétaires"
- Line label (large, display font)
- Status badge: ACTIVE / INACTIVE
- Category badge (color-coded pill)
- Department badge (if scoped)
- Edit button (pencil icon) — only if budget is DRAFT
- Deactivate (⋮ menu) — with guard per FR-BUD-028
Balance Card¶
Prominent card at top showing the 4 balance figures:
┌───────────────────────────────────┐
│ Allocation 5 000 000 XOF │
│ Engagé 2 100 000 XOF │
│ Réalisé 1 500 000 XOF │
│ ───────────────────────────── │
│ Disponible 1 400 000 XOF │
│ │
│ ████████████████░░░░░ 72% │
│ ⚠ Seuil d'avertissement atteint │
└───────────────────────────────────┘
- Available is visually separated (line divider above, bolder font)
- Progress bar: Large (20px height), colored by threshold zone
- Threshold indicator: Text below bar if any threshold is crossed. Icon + text:
- ⚠ Amber: "Seuil d'avertissement atteint (80%)"
- 🔴 Red: "Seuil d'alerte atteint (95%)"
- 🚫 Red bold: "Budget dépassé — {enforcement level description}"
Details Section¶
Collapsible sections:
Informations générales (expanded by default): - Catégorie: {name} - Service: {department name} or "Toute l'entreprise" - Compte SYSCOHADA: {account} or "Non associé" - Créée le: {date} par {user}
Seuils et contrôle (collapsed by default — progressive disclosure): - Niveau de contrôle: {WARN / REQUIRE_OVERRIDE / HARD_BLOCK} with explanation text - Seuil d'avertissement: {%} - Seuil d'alerte: {%} - Seuil d'action: {%} - "Utilise les paramètres par défaut" or "Seuils personnalisés" indicator - Edit button (goes to settings)
Historique des mouvements (collapsed by default): - Chronological list of all mutations on this line: - Reserve: "↗ Réservation de {amount} XOF — {commitment ref}" + date - Consume: "↘ Réalisation de {amount} XOF — {expense ref}" + date - Release: "↩ Libération de {amount} XOF — {commitment ref}" + date - Transfer in: "← Virement reçu de {source line} — {amount} XOF" + date - Transfer out: "→ Virement vers {dest line} — {amount} XOF" + date - Paginated (20 items per page) - Each entry shows: icon, description, amount, date, user
Actions (contextual)¶
- "Nouveau virement depuis cette ligne": Quick-link to transfer creation with source pre-filled. Shown if budget is ACTIVE + user has transfer permission.
- "Modifier": Edit line details (DRAFT only)
- "Désactiver": With guard check per FR-BUD-028
4.5 Transfers Tab — Virements¶
Design decisions applied: DD-01 (tab navigation), DD-06 (swipe/buttons)
Two sections, stacked vertically:
Pending Transfers Section¶
Header: "En attente" + count badge
If user is an approver (DG, P3b): - Pending transfers appear as approval cards (see §4.7 for swipe behavior)
If user is a requester (Comptable): - Pending transfers show with PENDING badge - Cancellable: "Annuler" link on each (per FR-BUD-047)
Empty state: "Aucun virement en attente" with subtle illustration
Transfer History Section¶
Header: "Historique" + expand/collapse toggle
List of completed transfers (APPROVED, REJECTED, CANCELLED): - Each entry: Source → Destination, amount, date, status badge, requester name - Status badges: - APPROVED: Green check + "Approuvé" - REJECTED: Red X + "Rejeté" - CANCELLED: Grey dash + "Annulé" - Tap to see full details (justification, approver, timestamps)
FAB / CTA¶
Mobile: "+" FAB (bottom-right) → navigates to Transfer Creation Desktop: "Nouveau virement" button in toolbar
4.6 Transfer Creation¶
Design decisions applied: DD-05 (visual "from → to" metaphor)
Layout¶
Full-screen form (mobile) / Modal or side panel (desktop — 600px max width)
Visual structure — 3 zones stacked vertically:
Zone 1: Source ("DEPUIS") - Label: "DEPUIS" (small caps, muted) - Select input: Searchable dropdown of active budget lines - After selection: Shows card with line label + category badge + available amount - Available amount highlighted: "Disponible : {amount} XOF"
Zone 2: Amount (center) - Animated flow indicator: Arrow pointing downward (subtle animation loop) - Amount input: Large, centered, prominent. "Montant (XOF)" label. - Thousands formatting as user types - Real-time validation: If amount > source available, input border turns red + inline error
Zone 3: Destination ("VERS") - Label: "VERS" (small caps, muted) - Select input: Same as source, but excludes the selected source line - After selection: Shows card with line label + current available + preview of new balance - "Disponible : 200 000 XOF → 700 000 XOF" (new balance in bold green)
Zone 4: Justification - Textarea: "Pourquoi ce virement ?" (placeholder) - Required field. Min 10 characters. - Character counter shown at 80+ chars (max 500)
Submit button: "Soumettre le virement" (full-width, primary)
Real-time balance preview: As the user fills in source, amount, and destination, both cards update to show: - Source: "Disponible : 1 400 000 → 900 000 XOF" (decrease, amber) - Destination: "Disponible : 200 000 → 700 000 XOF" (increase, green)
This live preview eliminates the need for a confirmation step — the user sees the impact before they submit.
DG Self-Approval¶
If the requester is the DG (per transfer approval routing table in PRD), after submit: - No PENDING state - Immediate success: "Virement approuvé automatiquement" (since DG is the approver) - Allocations update immediately - Logged as SELF_APPROVED in audit trail
4.7 Transfer Approval (DG/Finance Director)¶
Design decisions applied: DD-06 (swipe cards mobile, buttons desktop)
Mobile: Swipe Cards¶
Each pending transfer is a card:
┌─────────────────────────────────┐
│ ← REJETER APPROUVER → │
│ │
│ Salaires → Déplacements │
│ 500 000 XOF │
│ │
│ Par: Mme Koné (Comptable) │
│ Le 10/03/2026 │
│ "Mission imprévue à Bouaké" │
│ │
│ [Voir détails] │
└─────────────────────────────────┘
Swipe behavior: - Swipe right (→): Green "Approuver" background reveals. Release at threshold → approve. Haptic feedback. - Swipe left (←): Red "Rejeter" background reveals. Release → bottom sheet for rejection reason. - Partial swipe: Background color hints at the action, snaps back if released before threshold. - "Voir détails" link: Expands card to show source/destination balances, impact preview.
After approval: Card slides off-screen right with success check animation. Next pending card slides up. After rejection: Card slides off-screen left. Toast: "Virement rejeté."
Empty state after all processed: Celebration micro-animation + "Tout est à jour !" message.
Desktop: Inline Buttons¶
Table or card layout with explicit "Approuver" (green) and "Rejeter" (red outline) buttons per row. - "Approuver" button: One-click approve (no confirmation needed — undo available for 5 seconds via toast) - "Rejeter" button: Opens inline textarea for rejection reason, then "Confirmer le rejet"
Keyboard shortcuts (Enterprise):
- a: Approve selected transfer
- r: Reject selected transfer (opens reason input)
- ↑/↓: Navigate between pending transfers
Over-Budget Override Approval¶
Same pattern as transfer approval. Override requests appear in the Virements tab under a separate "Dépassements en attente" section.
Each override card shows: - Budget line name + current available - Requested amount + overage amount - Source: "Engagement" or "Dépense" + reference - Requester name + date - Impact preview: "Cette opération dépassera le budget de {overage} XOF"
4.8 Budget Settings¶
Accessible via ⋮ menu → "Paramètres" or from the header action menu
Layout¶
Full-screen (mobile) / Side panel or page (desktop)
Sections¶
Section 1: Seuils par défaut
Card with 3 threshold sliders: - Avertissement: Slider 1-200%, default 80%. Label: "Notification envoyée aux responsables" - Alerte: Slider 1-200%, default 95%. Label: "Notification urgente + email" - Action: Slider 1-200%, default 100%. Label: "Comportement selon le niveau de contrôle"
Validation: warn < alert < action. If violated: inline error "Les seuils doivent être croissants."
Visual: The 3 sliders are stacked with a shared visual bar showing the zones (green zone → amber zone → red zone).
Section 2: Niveau de contrôle par défaut
Radio group (3 options with descriptions): - Avertir seulement (WARN): "Les opérations sont autorisées même au-delà du budget. Vous recevez une alerte." - Demander une autorisation (REQUIRE_OVERRIDE): "Les opérations au-delà du budget nécessitent l'approbation du DG." - Bloquer (HARD_BLOCK): "Les opérations au-delà du budget sont interdites."
Default: WARN. Recommendation label on WARN: "(Recommandé pour débuter)"
Section 3: Catégories budgétaires
List of categories with: - Name (editable inline for custom categories, editable for system categories per FR-BUD-012) - Code (read-only) - SYSCOHADA prefix (read-only for system, editable for custom) - Status toggle (ACTIVE/INACTIVE) — with guard per FR-BUD-013 - Drag handle for sort order - "Créer une catégorie" button at bottom
Auto-save: All settings auto-save on change (per design principle #4). Subtle "Enregistré ✓" confirmation inline.
4.9 Manager View (Department-Scoped)¶
Design decisions applied: DD-07 (same layout, filtered + read-only)
When a Manager (N+1) opens the budget module, they are auto-routed to a filtered view.
Differences from Full View¶
| Aspect | Full View | Manager View |
|---|---|---|
| Tab bar | 3 tabs | 2 tabs: Tableau de bord | Lignes (no Virements) |
| Data scope | All budget lines | Only lines where org_unit_id matches manager's department (or children) |
| KPI cards | Company totals | Department totals |
| Mutations | Create, edit, transfer | None — read-only |
| Read-only badge | Not shown | Persistent banner: "Lecture seule — Budget de votre service" |
| Add line button | Shown (DRAFT) | Hidden |
| Settings | Accessible | Hidden |
| Export | Full data | Department data only |
Empty State (No Lines for Department)¶
"Aucune ligne budgétaire affectée à votre service." Subtext: "Contactez votre comptable ou votre DG pour créer des lignes budgétaires pour [department name]."
4.10 Budget Validation Ceremony¶
Design decisions applied: DD-09 (celebration moment)
When the DG taps "Valider le budget" (from ⋮ menu or Dashboard), a full-screen overlay appears.
Pre-Validation Summary¶
┌─────────────────────────────────────┐
│ Valider le budget │
│ │
│ Budget 2026 │
│ 01/01/2026 — 31/12/2026 │
│ │
│ ┌─ Récapitulatif ──────────────┐ │
│ │ 12 lignes budgétaires │ │
│ │ 5 catégories │ │
│ │ Allocation totale: │ │
│ │ 25 000 000 XOF │ │
│ └──────────────────────────────┘ │
│ │
│ ⚠ Une fois validé, les │
│ allocations seront verrouillées. │
│ Les modifications se feront │
│ uniquement par virement │
│ budgétaire. │
│ │
│ [Annuler] [Valider le budget] │
└─────────────────────────────────────┘
Post-Validation Celebration¶
On "Valider le budget" tap: 1. Button shows loading state (1-2s) 2. Overlay transitions: summary card scales down slightly 3. 🎊 Confetti animation bursts from center (2 seconds, using primary amber/gold particles) 4. Large checkmark animates in (scale bounce) 5. Text appears: "Budget validé !" (display font, large) 6. Subtext: "Validé le {date} par {DG name}" 7. Status badge on the budget changes from BROUILLON → ACTIF with a color morph animation 8. After 3 seconds: overlay fades, reveals Dashboard with ACTIVE budget
Sound: Optional subtle success chime (if device permits, user-configurable).
4.11 Year-End Closure Flow¶
Design decisions applied: DD-10 (two-step confirmation with warning)
Step 1: Closure Summary¶
Full-screen overlay or dedicated page:
┌─────────────────────────────────────┐
│ Clôturer le budget │
│ │
│ Budget 2026 — ACTIF │
│ 01/01/2026 — 31/12/2026 │
│ │
│ ┌─ Bilan final ─────────────────┐ │
│ │ Allocation: 25 000 000 XOF │ │
│ │ Engagé: 1 200 000 XOF │ │
│ │ Réalisé: 18 500 000 XOF │ │
│ │ Disponible: 5 300 000 XOF │ │
│ └───────────────────────────────┘ │
│ │
│ ⚠ ATTENTION │
│ 3 lignes ont des engagements en │
│ cours totalisant 1 200 000 XOF. │
│ Ces engagements seront perdus à │
│ la clôture. │
│ │
│ ┌─ Lignes avec engagements ─────┐ │
│ │ • Salaires: 500 000 XOF │ │
│ │ • Fournitures: 400 000 XOF │ │
│ │ • Déplacements: 300 000 XOF │ │
│ └───────────────────────────────┘ │
│ │
│ [Annuler] [Continuer →] │
└─────────────────────────────────────┘
If no open commitments: Warning section is hidden, flow goes directly to Step 2.
Step 2: Explicit Confirmation¶
┌─────────────────────────────────────┐
│ Cette action est irréversible. │
│ │
│ Tapez "CLÔTURER" pour confirmer : │
│ ┌─────────────────────────────┐ │
│ │ │ │
│ └─────────────────────────────┘ │
│ │
│ [Annuler] [Clôturer le budget] │
│ (disabled until typed) │
└─────────────────────────────────────┘
The "Clôturer le budget" button is disabled until the user types "CLÔTURER" (case-insensitive). This friction is intentional for an irreversible, once-per-year action.
Post-Closure¶
- Budget status → CLOSED
- Subtle transition animation: status badge morphs from green ACTIF to grey CLÔTURÉ
- Toast: "Budget 2026 clôturé. Les données restent accessibles en lecture seule."
- If a DRAFT budget for next year exists: Prompt card appears: "Le nouvel exercice a commencé. Voulez-vous activer le budget {year} ?"
4.12 Over-Budget Override Request¶
Shown to DG/P3b when a REQUIRE_OVERRIDE enforcement triggers
Appears as: 1. Push notification (if available): "Dépassement budgétaire — autorisation requise" 2. In-app notification in notification center 3. Card in Virements tab → "Dépassements en attente" section
Override Detail View¶
┌─────────────────────────────────────┐
│ Autorisation de dépassement │
│ │
│ Ligne: Fournitures de bureau │
│ Catégorie: Fournitures │
│ │
│ ┌─ Situation actuelle ──────────┐ │
│ │ Allocation: 3 000 000 XOF │ │
│ │ Consommé: 2 950 000 XOF │ │
│ │ Disponible: 50 000 XOF │ │
│ └───────────────────────────────┘ │
│ │
│ Opération demandée: │
│ Engagement de 200 000 XOF │
│ Dépassement: 150 000 XOF │
│ │
│ Demandé par: M. Traoré │
│ Le: 10/03/2026 │
│ Réf: ENG-2026-03-015 │
│ │
│ [Rejeter] [Autoriser] │
└─────────────────────────────────────┘
Same approval patterns as transfer approval (swipe mobile / buttons desktop).
5. Responsive Behavior¶
Breakpoint Strategy¶
| Breakpoint | Width | Layout Changes |
|---|---|---|
| Phone | 360px – 767px | Single column. Cards. Bottom FAB. Tabs full-width. Swipe gestures. |
| Tablet | 768px – 1023px | 2-column card grid. Tabs with full labels. Side-by-side KPIs. |
| Desktop | 1024px – 1439px | Data table view. Side panels for detail/creation. Full toolbar. |
| Large Desktop | 1440px+ | Max content width 1280px, centered. Dashboard gets 4-column KPI row. |
Key Responsive Adaptations¶
| Component | Phone | Tablet | Desktop |
|---|---|---|---|
| KPI cards | 2×2 grid | 4-column row | 4-column row |
| Budget lines | Cards, grouped | Cards, 2-column | Data table |
| Transfer creation | Full-screen form | Full-screen form | Modal (600px) or side panel |
| Approval cards | Swipe cards | Swipe cards | Inline buttons on table rows |
| Settings | Full-screen | Full-screen | Side panel (480px) |
| Line detail | Full-screen | Full-screen | Side panel (600px) or full-screen |
| Export | Bottom sheet | Bottom sheet | Dropdown from button |
| Navigation tabs | Icon + short label | Icon + full label | Icon + full label |
Thumb Zone Optimization (Mobile)¶
- Primary CTAs: Bottom of screen (thumb zone)
- Tab bar: Top, but large touch targets (48px height minimum)
- FAB for "+" actions: Bottom-right (natural thumb reach for right-handed users)
- Swipe gestures: Full card width (easy to initiate from anywhere)
- Back navigation: Top-left (standard, but also support system back gesture)
6. Offline Behavior¶
Principle¶
Per FR-PV-062: All financial mutations require connectivity. BUDMGT is read-only offline.
What Works Offline¶
| Feature | Offline Behavior |
|---|---|
| Dashboard KPIs | ✅ Cached values displayed |
| Budget lines list | ✅ Cached list displayed |
| Budget line detail | ✅ Cached detail displayed |
| Category breakdown | ✅ Cached |
| Transfer history | ✅ Cached (read-only) |
| Export | ❌ Not available offline |
| Create/edit budget line | ❌ Blocked |
| Create transfer | ❌ Blocked |
| Approve/reject transfer | ❌ Blocked |
| Validate budget | ❌ Blocked |
| Close budget | ❌ Blocked |
| Settings changes | ❌ Blocked |
Offline Visual Treatment¶
Staleness Banner (persistent, top of content area, below tabs):
┌─────────────────────────────────────┐
│ 🔶 Données hors ligne │
│ Dernière mise à jour : il y a 15 min│
└─────────────────────────────────────┘
- Background: Warm amber tint (not alarming red)
- Icon: Orange dot (matches sync status indicator)
- Updates relative time ("il y a 2 min", "il y a 1 heure", etc.)
- Tappable: Shows tooltip "Connectez-vous à Internet pour obtenir les données les plus récentes."
Disabled Actions: - All mutation buttons become visually muted (50% opacity) - On tap: Tooltip appears "Opération impossible hors ligne. Connectez-vous pour effectuer des modifications budgétaires." - FAB: Hidden offline - Swipe gestures: Disabled offline (cards show "Connexion requise")
Connection Transition: - Online → Offline: Banner slides in from top (300ms). Buttons fade to disabled (200ms). - Offline → Online: Banner slides out. Data auto-refreshes (skeleton shimmer on content). Buttons re-enable with fade-in.
Cache Strategy¶
- Pre-fetch: When online, cache the current budget + all lines + recent transfers in IndexedDB
- Cache invalidation: On every online visit, fresh data replaces cache
- Cache scope: Current tenant only (no cross-tenant cache)
- Cache persistence: Survives app restart and browser close
7. Motion Choreography¶
Page Entrance (Dashboard)¶
- Tab bar slides in from top (100ms)
- KPI cards stagger in: slide-up + fade, 60ms apart (cards 1→2→3→4)
- Consumption bar fills from left (600ms ease-out, after cards complete)
- Category breakdown items stagger in: slide-up + fade, 50ms apart
- Total entrance: ~1.2 seconds
Page Entrance (Budget Lines)¶
- Search/filter bar fades in (100ms)
- Category group headers stagger in (80ms apart)
- Cards within each group stagger (50ms apart, left-to-right on desktop grid)
- Cascading reveal effect: feels like content "settling into place"
Loading States¶
- Skeleton screens (never bare spinners):
- KPI cards: 4 skeleton cards with shimmer pulse
- Budget lines: 3-4 skeleton cards per category group
- Transfer cards: 2-3 skeleton cards
- Detail view: Skeleton header + skeleton balance card + skeleton sections
- Shimmer animation: Warm-toned gradient sweep (not cold grey)
Success Moments¶
| Action | Animation |
|---|---|
| Budget created | Card scale-up with sparkle glow → redirect |
| Budget validated | 🎊 Confetti (2s) + checkmark bounce + status badge morph |
| Transfer approved | Card slides off-screen right + ✓ icon flash |
| Transfer submitted | Success toast slides up from bottom + subtle pulse on pending count badge |
| Year-end closure | Status badge morph (green → grey) + "archived" shimmer effect |
| Line added (wizard) | Card slides down into list with bounce settle |
| Settings saved | Inline "Enregistré ✓" fade-in next to changed field |
Transitions¶
- Tab switch: Content cross-fades (200ms). No hard-cut.
- Navigate to detail: Content slides left (300ms) with slight scale-down of list behind.
- Modal/overlay open: Background dims (40% black overlay) + content slides up from bottom (mobile) or scales in from center (desktop).
- Back navigation: Reverse of forward animation (slide right, scale up).
Reduce Motion¶
When user has prefers-reduced-motion:
- All animations replaced with simple opacity fades (150ms)
- No confetti, no slide, no bounce
- Skeleton shimmer becomes static pulse (opacity change only)
8. Loading, Empty, Error & Success States¶
Loading States¶
| Screen | Skeleton Description |
|---|---|
| Dashboard | 4 KPI skeleton cards (2×2) + skeleton bar + 3 skeleton category rows |
| Budget lines | 2 skeleton category headers + 3 skeleton cards each |
| Line detail | Skeleton title + skeleton balance card + 2 skeleton sections |
| Transfers | 2 skeleton transfer cards + skeleton history header |
| Settings | 3 skeleton section headers + skeleton form fields |
Empty States¶
| Context | Illustration | Headline | Subtext | CTA |
|---|---|---|---|---|
| No budget exists (first time) | Paper→digital transformation illustration | "Créez votre premier budget" | "En quelques minutes, donnez-vous une vision claire de vos dépenses." | "Commencer" → Wizard |
| Budget exists but no lines (DRAFT) | Empty clipboard illustration | "Ajoutez vos premières lignes" | "Les lignes budgétaires représentent vos postes de dépenses." | "+ Ajouter une ligne" |
| No pending transfers | Calm/zen illustration (all settled) | "Aucun virement en attente" | "Les demandes de virement apparaîtront ici." | — |
| No transfer history | Clock illustration | "Pas encore de virements" | "L'historique de vos virements budgétaires s'affichera ici." | — |
| Manager view: no dept lines | Building/department illustration | "Aucune ligne budgétaire affectée à votre service" | "Contactez votre comptable ou votre DG pour créer des lignes budgétaires pour {department}." | — |
| Offline: no cache | Cloud-offline illustration | "Données non disponibles hors ligne" | "Connectez-vous à Internet pour charger le budget." | — |
| Search returns no results | Magnifying glass illustration | "Aucun résultat pour « {query} »" | "Essayez un autre terme de recherche." | "Effacer la recherche" |
Error States¶
| Error | Display | French Message |
|---|---|---|
| API failure (general) | Toast (bottom) + retry | "Une erreur est survenue. Veuillez réessayer." |
| Transfer amount exceeds available | Inline on amount field (red border + text) | "Montant insuffisant sur la ligne source. Disponible : {amount} XOF." |
| Budget line deactivation blocked | Toast (bottom, persistent until dismissed) | "Cette ligne a des engagements en cours ({amount} XOF). Annulez-les avant de désactiver." |
| Category deactivation blocked | Toast (bottom) | "Cette catégorie est utilisée par {N} lignes budgétaires actives. Réaffectez-les avant de désactiver." |
| Decimal amount entered | Inline on amount field | "Les montants en XOF doivent être des nombres entiers." |
| Threshold order invalid | Inline below sliders | "Les seuils doivent être croissants : avertissement < alerte < action." |
| Budget already validated | Toast | "Ce budget est déjà validé." |
| Offline mutation attempt | Tooltip on disabled button | "Opération impossible hors ligne. Connectez-vous pour effectuer des modifications budgétaires." |
| Concurrent edit conflict | Modal with side-by-side | "Ce virement a été modifié par un autre utilisateur. Veuillez actualiser." + "Actualiser" button |
| Justification too short | Inline on textarea | "La justification doit contenir au moins 10 caractères." |
Success States¶
| Action | Display | French Message | Animation |
|---|---|---|---|
| Budget created | Redirect + toast | "Budget créé avec succès !" | Sparkle glow on card |
| Budget validated | Full-screen overlay | "Budget validé !" | Confetti + checkmark bounce |
| Budget closed | Toast + status change | "Budget {year} clôturé." | Status badge morph |
| Line added | Toast + card insertion | "Ligne « {name} » ajoutée." | Card slides into list |
| Line updated | Inline "saved" indicator | "Modifications enregistrées." | Fade-in ✓ |
| Transfer submitted | Toast | "Demande de virement soumise." | Pulse on pending badge |
| Transfer approved | Card exit + toast | "Virement approuvé." | Card slides right |
| Transfer rejected | Card exit + toast | "Virement rejeté." | Card slides left |
| Override approved | Card exit + toast | "Dépassement autorisé." | Card slides right |
| Settings saved | Inline indicator | "Enregistré ✓" | Fade-in next to field |
| Export started | Toast | "Export en cours…" then "Export terminé. Téléchargement en cours." | — |
9. Component Specifications¶
9.1 BudgetKPICard¶
Purpose: Display a single budget metric (allocation, committed, spent, available)
Props:
- label: string (e.g., "Allocation totale")
- amount: number (formatted as XOF)
- accentColor: theme token (primary, teal, deepAmber, semantic)
- trend?: "up" | "down" | "neutral" (optional trend indicator)
- isLoading: boolean (shows skeleton)
States: - Default: Amount + label + accent tint background - Loading: Skeleton with shimmer - Warning: If "Disponible" card and amount < 10% of allocation → red accent
Accessibility:
- role="status" + aria-label in French (e.g., "Allocation totale : 25 millions de francs CFA")
- High contrast border for color-blind users
9.2 BudgetProgressBar¶
Purpose: Visualize budget consumption with threshold coloring
Props:
- allocation: number
- committed: number
- spent: number
- warnThreshold: number (default 80)
- alertThreshold: number (default 95)
- actionThreshold: number (default 100)
- enforcementLevel?: "WARN" | "REQUIRE_OVERRIDE" | "HARD_BLOCK"
- size: "sm" (12px) | "md" (16px) | "lg" (20px)
- showLabel: boolean (show % text)
- animated: boolean (entrance animation)
Segments: - Committed portion: Teal fill - Spent portion: Deep amber fill - Available portion: Light green fill (empty space)
Threshold coloring (applied to the bar background/border): - < warnThreshold: Green zone (no indicator) - ≥ warnThreshold & < alertThreshold: Amber zone (⚠ icon if showLabel) - ≥ alertThreshold: Red zone (🔴 icon if showLabel)
Enforcement indicator (if enforcementLevel is set): - Small shield icon at the right end of bar - HARD_BLOCK: 🛡️ red - REQUIRE_OVERRIDE: 🛡️ amber - WARN: no icon
Accessibility:
- role="progressbar" with aria-valuenow, aria-valuemin, aria-valuemax
- aria-label: "Consommation budgétaire : {pct} pourcent. {committed} engagé, {spent} réalisé, {available} disponible."
9.3 BudgetLineCard¶
Purpose: Display a budget line summary in card format
Props:
- line: BudgetLine object
- isExpandable: boolean (tap to show full breakdown)
- isReadOnly: boolean (manager view)
- onTap: callback (navigate to detail)
Layout:
┌─────────────────────────────────┐
│ {label} {%} │
│ {BudgetProgressBar size="sm"} │
│ Disponible: {available} XOF │
│ [dept badge] [enforcement icon]│
└─────────────────────────────────┘
Expanded state (when tapped in list, before navigating to detail):
┌─────────────────────────────────┐
│ {label} {%} │
│ {BudgetProgressBar size="md"} │
│ │
│ Allocation: {allocation} XOF │
│ Engagé: {committed} XOF │
│ Réalisé: {spent} XOF │
│ Disponible: {available} XOF │
│ │
│ [dept badge] [enforcement icon]│
│ [Voir détails →] │
└─────────────────────────────────┘
States: - Default: Collapsed (label + bar + available) - Expanded: Full breakdown - Loading: Skeleton card - Warning: Amber card border if ≥ warn threshold - Critical: Red card border if ≥ alert threshold - Inactive: Greyed out, "INACTIVE" badge
Shadow hierarchy: - Resting: Subtle shadow (elevation 1) - Hover (desktop): Lifted shadow (elevation 2) - Active/pressed: Pressed shadow (elevation 0.5) - Expanded: Elevated shadow (elevation 3)
9.4 TransferApprovalCard¶
Purpose: Swipeable card for transfer/override approval
Props:
- transfer: BudgetTransfer object (or BudgetOverrideRequest)
- onApprove: callback
- onReject: callback (receives rejection reason)
- isSwipeable: boolean (true on mobile, false on desktop)
States: - Default: Card with transfer details - Swiping right: Green background reveals, "Approuver" text visible - Swiping left: Red background reveals, "Rejeter" text visible - Approved: Card slides off-screen right - Rejected: Card slides off-screen left
Desktop fallback: Explicit "Approuver" / "Rejeter" buttons replace swipe.
9.5 OfflineBanner¶
Purpose: Persistent banner indicating offline state and data staleness
Props:
- lastSyncTimestamp: Date
- isOnline: boolean
States: - Online: Hidden (0 height) - Offline: Visible, warm amber background, shows relative time since last sync - Transitioning online→offline: Slides in from top (300ms) - Transitioning offline→online: Slides out upward (300ms)
9.6 FiscalYearSelector¶
Purpose: Switch between fiscal year budgets (when both ACTIVE + DRAFT coexist)
Props:
- budgets: array of Budget objects
- currentBudgetId: string
- onSelect: callback
Layout: Dropdown/pill toggle showing "{year} — {status badge}"
9.7 ThresholdSliderGroup¶
Purpose: Three linked sliders for threshold configuration
Props:
- warnValue: number
- alertValue: number
- actionValue: number
- onChange: callback
Visual: Three sliders on a shared track. The track is color-zoned (green → amber → red). Sliders cannot cross each other (drag constrained).
Accessibility: Each slider has aria-label, aria-valuemin, aria-valuemax, aria-valuenow.
10. Enterprise Brand Divergence¶
For the ALTARYS ENTERPRISE HR Suite, the following adaptations apply:
Visual Treatment¶
| Aspect | Papillon | Enterprise |
|---|---|---|
| Primary color | Warm amber (#F59E0B) | Deep navy (#1E3A5F) |
| Accent color | Forest green / teal | Electric blue / refined gold |
| Background | Warm off-white gradient | Clean white / very light grey |
| Card shadows | Warm-toned, medium depth | Crisp, minimal |
| Typography | Warm display font + clean body | Inter or similar neutral sans-serif |
| Density | Generous whitespace, large touch targets | Compact, information-dense |
| KPI cards | Large (mobile 2×2, desktop 4-col) | Compact row of 6-8 KPIs above fold |
Layout Differences¶
Dashboard (Enterprise): - 6-8 KPI cards in a single dense row (add: Total engagé %, Total réalisé %, Budget restant %, Lines at risk count) - Data table as primary view (not cards) - Treemap visualization option (toggle between bar chart and treemap) - Split-pane: left = chart area, right = data table
Budget Lines (Enterprise): - Default view: Data table (always, not cards) - Advanced filters panel (collapsible left sidebar): Category, department, enforcement level, threshold status, amount range - Batch operations: Select multiple lines → batch export, batch threshold change (V2 prep) - Keyboard navigation throughout
Transfers (Enterprise): - Table view with batch approve capability (V2 prep: select multiple → approve all) - Keyboard shortcuts prominent (shown in toolbar hints)
Settings (Enterprise): - Full page (not side panel) - Additional sections: API integration settings, Audit log viewer inline
Onboarding Difference¶
| Papillon | Enterprise |
|---|---|
| Guided wizard with tooltips | Quick-start modal dismissible in one click |
| Empty states with illustrations | Empty states with text only + "Import from Excel" CTA (V2) |
| Contextual tips persist for 3 sessions | Tips shown once, then gone |
| Celebration animations | Subtle confirmation toasts only |
11. French Micro-copy¶
Navigation & Headers¶
| Key | French | Context |
|---|---|---|
tab.dashboard |
Tableau de bord | Tab label |
tab.lines |
Lignes budgétaires | Tab label |
tab.transfers |
Virements | Tab label |
header.budget |
Budget {year} | Module header |
badge.draft |
Brouillon | Status badge |
badge.active |
Actif | Status badge |
badge.closed |
Clôturé | Status badge |
badge.readOnly |
Lecture seule | Manager view badge |
KPI Labels¶
| Key | French |
|---|---|
kpi.allocation |
Allocation totale |
kpi.committed |
Engagé |
kpi.spent |
Réalisé |
kpi.available |
Disponible |
kpi.consumption |
Consommation |
kpi.byCategory |
Par catégorie |
kpi.byDepartment |
Par service |
Wizard¶
| Key | French |
|---|---|
wizard.title |
Créez votre premier budget |
wizard.subtitle |
En quelques minutes, donnez-vous une vision claire de vos dépenses. |
wizard.start |
Commencer |
wizard.step1.title |
Paramètres du budget |
wizard.step1.name |
Nom du budget |
wizard.step1.fiscalYear |
Exercice fiscal |
wizard.step1.effectiveStart |
Date de début effective |
wizard.step1.effectiveStartHint |
Votre budget démarrera à partir de cette date. |
wizard.step2.title |
Ajoutez vos lignes budgétaires |
wizard.step2.hint |
Commencez par les postes de dépenses les plus importants. Vous pourrez en ajouter d'autres plus tard. |
wizard.step2.addLine |
+ Ajouter une ligne |
wizard.step2.minLines |
Ajoutez au moins une ligne budgétaire. |
wizard.step3.title |
Récapitulatif |
wizard.step3.total |
Allocation totale |
wizard.step3.lineCount |
{count} lignes budgétaires |
wizard.step3.draftInfo |
Ce budget sera créé en mode brouillon. Le Directeur Général pourra le valider pour le rendre officiel. |
wizard.step3.thresholdTip |
Astuce : vous pouvez configurer des seuils d'alerte dans Paramètres > Seuils après la création. |
wizard.create |
Créer le budget |
wizard.success |
Budget créé avec succès ! |
Budget Lines¶
| Key | French |
|---|---|
lines.search |
Rechercher une ligne… |
lines.all |
Toutes |
lines.sort.category |
Par catégorie |
lines.sort.consumption |
Par consommation ↓ |
lines.sort.available |
Par disponible ↑ |
lines.sort.alpha |
Alphabétique |
lines.available |
Disponible |
lines.addLine |
+ Ajouter une ligne |
lines.allocation |
Allocation |
lines.committed |
Engagé |
lines.spent |
Réalisé |
lines.consumption |
Consommation |
Budget Line Form¶
| Key | French |
|---|---|
lineForm.category |
Catégorie |
lineForm.createCategory |
Créer une catégorie |
lineForm.label |
Libellé |
lineForm.allocation |
Montant alloué (XOF) |
lineForm.department |
Service (optionnel) |
lineForm.departmentDefault |
Toute l'entreprise |
lineForm.syscohada |
Souhaitez-vous associer un compte SYSCOHADA ? |
lineForm.syscohadaSkip |
Passer |
lineForm.add |
Ajouter |
lineForm.cancel |
Annuler |
Transfers¶
| Key | French |
|---|---|
transfers.pending |
En attente |
transfers.history |
Historique |
transfers.new |
Nouveau virement |
transfers.from |
DEPUIS |
transfers.to |
VERS |
transfers.amount |
Montant (XOF) |
transfers.justification |
Pourquoi ce virement ? |
transfers.justificationMin |
La justification doit contenir au moins 10 caractères. |
transfers.submit |
Soumettre le virement |
transfers.submitted |
Demande de virement soumise. |
transfers.selfApproved |
Virement approuvé automatiquement. |
transfers.approved |
Virement approuvé. |
transfers.rejected |
Virement rejeté. |
transfers.cancelled |
Virement annulé. |
transfers.cancel |
Annuler ce virement |
transfers.approve |
Approuver |
transfers.reject |
Rejeter |
transfers.rejectReason |
Motif du rejet |
transfers.balancePreview |
Disponible : {before} → {after} XOF |
transfers.insufficientAmount |
Montant insuffisant sur la ligne source. Disponible : {amount} XOF. |
Validation & Closure¶
| Key | French |
|---|---|
validate.title |
Valider le budget |
validate.summary |
Récapitulatif |
validate.lineCount |
{count} lignes budgétaires |
validate.categoryCount |
{count} catégories |
validate.warning |
Une fois validé, les allocations seront verrouillées. Les modifications se feront uniquement par virement budgétaire. |
validate.confirm |
Valider le budget |
validate.success |
Budget validé ! |
validate.stamp |
Validé le {date} par {name} |
close.title |
Clôturer le budget |
close.openCommitmentsWarning |
{count} lignes ont des engagements en cours totalisant {amount} XOF. Ces engagements seront perdus à la clôture. |
close.irreversible |
Cette action est irréversible. |
close.typeConfirm |
Tapez "CLÔTURER" pour confirmer : |
close.confirm |
Clôturer le budget |
close.success |
Budget {year} clôturé. Les données restent accessibles en lecture seule. |
close.nextYearPrompt |
Le nouvel exercice a commencé. Voulez-vous activer le budget {year} ? |
Settings¶
| Key | French |
|---|---|
settings.title |
Paramètres du budget |
settings.thresholds |
Seuils par défaut |
settings.warnThreshold |
Avertissement |
settings.warnDesc |
Notification envoyée aux responsables |
settings.alertThreshold |
Alerte |
settings.alertDesc |
Notification urgente + email |
settings.actionThreshold |
Action |
settings.actionDesc |
Comportement selon le niveau de contrôle |
settings.thresholdError |
Les seuils doivent être croissants : avertissement < alerte < action. |
settings.enforcement |
Niveau de contrôle par défaut |
settings.warn |
Avertir seulement |
settings.warnExplain |
Les opérations sont autorisées même au-delà du budget. Vous recevez une alerte. |
settings.requireOverride |
Demander une autorisation |
settings.requireOverrideExplain |
Les opérations au-delà du budget nécessitent l'approbation du DG. |
settings.hardBlock |
Bloquer |
settings.hardBlockExplain |
Les opérations au-delà du budget sont interdites. |
settings.recommended |
(Recommandé pour débuter) |
settings.categories |
Catégories budgétaires |
settings.createCategory |
Créer une catégorie |
settings.saved |
Enregistré ✓ |
Override¶
| Key | French |
|---|---|
override.title |
Autorisation de dépassement |
override.currentSituation |
Situation actuelle |
override.requestedOp |
Opération demandée |
override.overage |
Dépassement |
override.approve |
Autoriser |
override.reject |
Rejeter |
override.approved |
Dépassement autorisé. |
override.rejected |
Dépassement rejeté. |
Errors & Offline¶
| Key | French |
|---|---|
error.general |
Une erreur est survenue. Veuillez réessayer. |
error.amountNotInteger |
Les montants en XOF doivent être des nombres entiers. |
error.lineHasCommitments |
Cette ligne a des engagements en cours ({amount} XOF). Annulez-les avant de désactiver. |
error.categoryInUse |
Cette catégorie est utilisée par {count} lignes budgétaires actives. Réaffectez-les avant de désactiver. |
error.budgetLocked |
Le budget est validé. Utilisez un virement budgétaire pour modifier les allocations. |
error.budgetAlreadyValidated |
Ce budget est déjà validé. |
error.hardBlock |
Budget insuffisant sur la ligne « {label} ». Disponible : {available} XOF. Demandé : {amount} XOF. |
offline.banner |
Données hors ligne |
offline.lastSync |
Dernière mise à jour : {relativeTime} |
offline.mutationBlocked |
Opération impossible hors ligne. Connectez-vous pour effectuer des modifications budgétaires. |
offline.noCache |
Données non disponibles hors ligne. Connectez-vous à Internet pour charger le budget. |
offline.connectionLost |
Connexion perdue. Vos données sont toujours accessibles en lecture. |
offline.connectionRestored |
Connexion rétablie. Mise à jour en cours… |
Empty States¶
| Key | French |
|---|---|
empty.noBudget |
Créez votre premier budget |
empty.noBudgetSub |
En quelques minutes, donnez-vous une vision claire de vos dépenses. |
empty.noLines |
Ajoutez vos premières lignes |
empty.noLinesSub |
Les lignes budgétaires représentent vos postes de dépenses. |
empty.noPending |
Aucun virement en attente |
empty.noPendingSub |
Les demandes de virement apparaîtront ici. |
empty.noHistory |
Pas encore de virements |
empty.noHistorySub |
L'historique de vos virements budgétaires s'affichera ici. |
empty.noDeptLines |
Aucune ligne budgétaire affectée à votre service |
empty.noDeptLinesSub |
Contactez votre comptable ou votre DG pour créer des lignes budgétaires pour {department}. |
empty.noSearchResults |
Aucun résultat pour « {query} » |
empty.noSearchResultsSub |
Essayez un autre terme de recherche. |
empty.allApproved |
Tout est à jour ! |
Movement History (Line Detail)¶
| Key | French |
|---|---|
movement.reserve |
Réservation de {amount} XOF — {ref} |
movement.consume |
Réalisation de {amount} XOF — {ref} |
movement.release |
Libération de {amount} XOF — {ref} |
movement.transferIn |
Virement reçu de « {source} » — {amount} XOF |
movement.transferOut |
Virement vers « {dest} » — {amount} XOF |
12. Brand Compliance Checklist¶
Papillon HR Suite¶
- [x] Amber/gold primary color used (KPI accent, progress bars, CTAs, confetti particles)
- [x] Mobile-first layout (360px designed first — all screens specified mobile-first)
- [x] Offline states specified for ALL write operations (§6 — read-only cache + staleness banner + disabled mutations)
- [x] Touch targets 48px minimum (tab bar, cards, buttons, swipe zones)
- [x] French micro-copy warm and human (§11 — "Créez votre premier budget", not "Nouveau budget")
- [x] Loading skeletons (not spinners) specified (§7 — warm-toned shimmer)
- [x] Generous whitespace — not crowded (single column mobile, category grouping reduces visual noise)
- [x] Celebration animation specified for milestone actions (validation ceremony: confetti + checkmark)
- [x] Motion choreography specified (§7 — staggered entrance, success moments, reduced motion fallback)
- [x] Background depth specified (warm gradient backgrounds, card shadow hierarchy)
- [x] Swipe gestures for common actions (transfer approval on mobile)
- [x] Auto-save on settings changes
- [x] Undo-friendly: transfer approval has 5s undo window on desktop
ALTARYS ENTERPRISE HR Suite¶
- [x] Navy/corporate color palette used (§10 — deep navy primary, electric blue accent)
- [x] Desktop-primary layout (1440px designed first in §10 divergence)
- [x] Information density appropriate for power users (6-8 KPI cards, data table default, compact layout)
- [x] Batch operation flows specified (batch approve prep, batch export in §10)
- [x] Keyboard shortcuts specified for common actions (§4.3, §4.7 — navigation, approve, reject, search, export, new line)
- [x] Advanced filter/sort panels included (§10 — collapsible left sidebar with category, department, enforcement, threshold, amount range)
- [x] Export to CSV/Excel specified (§4.2 — dashboard export, department-scoped export for managers)
- [x] Treemap visualization option for power users (§10)
- [x] Minimal onboarding — quick-start dismissible in one click (§10)
End of Design Document for Budget Lines Management (BUDMGT) v1.0