# ROA2WEB Mobile Patterns Library

**Version:** 3.0.0
**Last Updated:** 2026-01-12
**Status:** ✅ Complete (Phase 3 - Mobile Navigation Overhaul)

---

## Table of Contents

1. [Quick Start](#quick-start)
2. [Mobile Layout Overview](#mobile-layout-overview)
3. [Navigation Architecture](#navigation-architecture)
4. [MobileTopBar](#mobiletopbar)
5. [MobileBottomNav](#mobilebottomnav) *(UPDATED - Phase 3)*
6. [MobileDrawerMenu](#mobiledrawermenu) *(UPDATED - Phase 3)*
7. [Mobile Tab Pattern](#mobile-tab-pattern) *(NEW - Phase 3)*
8. [FAB Pattern](#fab-pattern) *(NEW - Phase 3)*
9. [MobileActionBar](#mobileactionbar)
10. [MobileSelectionFooter](#mobileselectionfooter)
11. [BottomSheet](#bottomsheet)
12. [SwipeableCards](#swipeablecards)
13. [Design Tokens for Mobile](#design-tokens-for-mobile)
14. [Best Practices](#best-practices)
15. [Troubleshooting](#troubleshooting)

---

## Quick Start

### For New Developers

Get a mobile view running in **5 minutes**:

```vue
<template>
  <div class="mobile-view">
    <!-- 1. Top Bar -->
    <MobileTopBar
      title="My View"
      :showMenu="true"
      :actions="topBarActions"
      @menu-click="showDrawer = true"
      @action-click="handleAction"
    />

    <!-- 2. Drawer Menu (hamburger navigation) -->
    <MobileDrawerMenu
      v-model="showDrawer"
      :user="currentUser"
      @logout="handleLogout"
    />

    <!-- 3. Main Content (with padding for fixed bars) -->
    <main class="mobile-content">
      <!-- Your content here -->
    </main>

    <!-- 4. Bottom Navigation -->
    <MobileBottomNav />
  </div>
</template>

<script setup>
import { ref } from 'vue'
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
import MobileDrawerMenu from '@shared/components/mobile/MobileDrawerMenu.vue'

const showDrawer = ref(false)
const currentUser = { username: 'John Doe' }

const topBarActions = [
  { icon: 'pi pi-filter', label: 'Filter', tooltip: 'Filtrează' }
]

const handleLogout = () => {
  // Handle logout
}
</script>

<style scoped>
.mobile-content {
  padding-top: 56px;    /* MobileTopBar height */
  padding-bottom: 56px; /* MobileBottomNav height */
  min-height: 100vh;
}
</style>
```

### Import Paths

All mobile components are located in `src/shared/components/mobile/`:

```javascript
import MobileTopBar from '@shared/components/mobile/MobileTopBar.vue'
import MobileBottomNav from '@shared/components/mobile/MobileBottomNav.vue'
import MobileDrawerMenu from '@shared/components/mobile/MobileDrawerMenu.vue'
import MobileActionBar from '@shared/components/mobile/MobileActionBar.vue'
import MobileSelectionFooter from '@shared/components/mobile/MobileSelectionFooter.vue'
import BottomSheet from '@shared/components/mobile/BottomSheet.vue'
import SwipeableCards from '@shared/components/mobile/SwipeableCards.vue'
```

---

## Mobile Layout Overview

### ASCII Diagram: Standard Mobile Layout (Phase 3)

```
┌─────────────────────────────────────────┐
│         MobileTopBar (56px)             │
│  [≡]        Page Title      [📥] [🔍]  │
├─────────────────────────────────────────┤
│                                         │
│                                         │
│              MAIN CONTENT               │
│                                         │
│         (scrollable area)               │
│                                         │
│     padding-top: 56px                   │
│     padding-bottom: 56px                │
│                                    [+]  │  ← FAB (contextual)
│                                         │
├─────────────────────────────────────────┤
│        MobileBottomNav (56px)           │
│   🏠        📋       📄       ⚙️        │
│ Dashboard  Bonuri  Facturi  Setări      │
└─────────────────────────────────────────┘
```

> **Phase 3 Changes:**
> - Footer Nav: 4 direct links (Dashboard, Bonuri, Facturi, Setări)
> - Upload moved to FAB on Bonuri page
> - Rapoarte removed from footer (accessible via Hamburger Menu)

### ASCII Diagram: Drawer Menu Open (Phase 3 - Grouped Categories)

```
┌──────────────────┬──────────────────────┐
│  MobileDrawer    │ ░░░░░░░░░░░░░░░░░░░░ │
│  Menu (280px)    │ ░░░░░░░░░░░░░░░░░░░░ │
├──────────────────┤ ░░░ OVERLAY ░░░░░░░░ │
│  🏢 ROA2WEB      │ ░░ (tap to close) ░░ │
├──────────────────┤ ░░░░░░░░░░░░░░░░░░░░ │
│  PRINCIPALE      │ ░░░░░░░░░░░░░░░░░░░░ │
│  🏠 Dashboard    │ ░░░░░░░░░░░░░░░░░░░░ │
│  📋 Bonuri       │ ░░░░░░░░░░░░░░░░░░░░ │
│  ──────────────  │ ░░░░░░░░░░░░░░░░░░░░ │
│  RAPOARTE        │ ░░░░░░░░░░░░░░░░░░░░ │
│  📄 Facturi      │ ░░░░░░░░░░░░░░░░░░░░ │
│  🔢 Balanță      │ ░░░░░░░░░░░░░░░░░░░░ │
│  💰 Casa și Banca│ ░░░░░░░░░░░░░░░░░░░░ │
│  ──────────────  │ ░░░░░░░░░░░░░░░░░░░░ │
│  ANALIZE         │ ░░░░░░░░░░░░░░░░░░░░ │
│  ⏰ Scadențe     │ ░░░░░░░░░░░░░░░░░░░░ │
│  📋 Facturi Det. │ ░░░░░░░░░░░░░░░░░░░░ │
│  ──────────────  │ ░░░░░░░░░░░░░░░░░░░░ │
│  ADMINISTRARE    │ ░░░░░░░░░░░░░░░░░░░░ │
│  ⚙️ Setări       │ ░░░░░░░░░░░░░░░░░░░░ │
├──────────────────┤ ░░░░░░░░░░░░░░░░░░░░ │
│  👤 Username     │ ░░░░░░░░░░░░░░░░░░░░ │
│  🚪 Deconectare  │ ░░░░░░░░░░░░░░░░░░░░ │
└──────────────────┴──────────────────────┘
```

> **Phase 3 Changes:**
> - Navigation organized into 4 category sections with visual separators
> - PRINCIPALE: Dashboard, Bonuri
> - RAPOARTE: Facturi, Balanță, Casa și Banca
> - ANALIZE: Scadențe, Facturi Detaliate
> - ADMINISTRARE: Setări

### ASCII Diagram: Selection Mode Layout

```
┌─────────────────────────────────────────┐
│      MobileTopBar (selection-active)    │
│  [←]      "3 selectate"      [☑] [✕]   │
├─────────────────────────────────────────┤
│                                         │
│     ☑ Item 1                            │
│     ☐ Item 2                            │
│     ☑ Item 3                            │
│     ☑ Item 4                            │
│     ☐ Item 5                            │
│                                         │
│                                         │
├─────────────────────────────────────────┤
│      MobileSelectionFooter              │
│  ┌──────────┐    ┌──────────┐          │
│  │  🗑 Șterge │    │ 📤 Export │          │
│  └──────────┘    └──────────┘          │
└─────────────────────────────────────────┘
```

### ASCII Diagram: Action Bar Layout (Edit/Create Views)

```
┌─────────────────────────────────────────┐
│         MobileTopBar (56px)             │
│  [←]        Editare Bon         [⋮]     │
├─────────────────────────────────────────┤
│                                         │
│     Form Fields...                      │
│                                         │
│     ┌─────────────────────────────┐     │
│     │  Furnizor: LIDL             │     │
│     │  Total: 125.50 RON          │     │
│     │  Data: 2026-01-12           │     │
│     └─────────────────────────────┘     │
│                                         │
├─────────────────────────────────────────┤
│      MobileActionBar (context-aware)    │
│  ┌──────────┐    ┌──────────────────┐  │
│  │ Salvează │    │ Trimite aprobare │  │
│  └──────────┘    └──────────────────┘  │
├─────────────────────────────────────────┤
│        MobileBottomNav (56px)           │
└─────────────────────────────────────────┘
```

### ASCII Diagram: BottomSheet Open

```
┌─────────────────────────────────────────┐
│         MobileTopBar (56px)             │
├─────────────────────────────────────────┤
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░ OVERLAY ░░░░░░░░░░░░░░░░░░ │
│ ░░░░░░░░░░ (tap to close) ░░░░░░░░░░░░░ │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ │
├─────────────────────────────────────────┤  ←─ BottomSheet
│            ───────────                  │     slides up
│            (drag handle)                │
│                                         │
│     Filter Options:                     │
│     ☐ Option A                          │
│     ☑ Option B                          │
│     ☐ Option C                          │
│                                         │
│     [  Apply Filters  ]                 │
│                                         │
└─────────────────────────────────────────┘
```

### ASCII Diagram: SwipeableCards

```
┌─────────────────────────────────────────┐
│                                         │
│ ┌─────────────────────────────────────┐ │
│ │                                     │ │
│ │         KPI Card Content            │ │  ← Swipe left/right
│ │                                     │ │    to navigate
│ │         $125,430                    │ │
│ │         Total Sales                 │ │
│ │                                     │ │
│ └─────────────────────────────────────┘ │
│                                         │
│              ●━━━━●───●                 │  ← Dots indicator
│                                         │    (active = expanded)
└─────────────────────────────────────────┘
```

### ASCII Diagram: Mobile Tab Pattern (Phase 3)

```
┌─────────────────────────────────────────┐
│         MobileTopBar (56px)             │
│  [≡]        Facturi          [📥] [🔍] │
├─────────────────────────────────────────┤
│┌──────────────────┬────────────────────┐│
││     Clienți      │     Furnizori      ││  ← Full-width tabs
││   ═══════════    │                    ││    (Material Design 3)
│└──────────────────┴────────────────────┘│
├─────────────────────────────────────────┤
│                                         │
│              TAB CONTENT                │
│        (changes based on tab)           │
│                                         │
│     padding-top: 104px (56+48)          │
│                                         │
├─────────────────────────────────────────┤
│        MobileBottomNav (56px)           │
│   🏠        📋       📄       ⚙️        │
│ Dashboard  Bonuri  Facturi  Setări      │
└─────────────────────────────────────────┘
```

> **Used in:** Facturi (`/reports/invoices`), Scadențe (`/reports/maturity-analysis`)

### ASCII Diagram: FAB Pattern (Phase 3)

```
┌─────────────────────────────────────────┐
│         MobileTopBar (56px)             │
│  [≡]        Bonuri           [📥] [🔍] │
├─────────────────────────────────────────┤
│                                         │
│              MAIN CONTENT               │
│                                         │
│                         ┌─────────────┐ │
│                         │  Upload     │ │  ← FAB Popup Menu
│                         │  Bulk       │ │    (appears on tap)
│                         ├─────────────┤ │
│                         │  Bon Nou    │ │
│                         └─────────────┘ │
│                               [+]       │  ← FAB (56x56px)
│                                         │     bottom: 72px
├─────────────────────────────────────────┤
│        MobileBottomNav (56px)           │
│   🏠        📋       📄       ⚙️        │
│ Dashboard  Bonuri  Facturi  Setări      │
└─────────────────────────────────────────┘
```

> **Used in:** Bonuri page (`/data-entry`) - Upload moved from footer to FAB

---

## Navigation Architecture

### Route Map (Phase 3 - Updated)

```
                    ┌─────────────────────────────────────┐
                    │           / (root)                  │
                    │     Redirects to /dashboard         │
                    └───────────────┬─────────────────────┘
                                    │
        ┌───────────────────────────┼───────────────────────────┐
        │                           │                           │
        ▼                           ▼                           ▼
┌───────────────────┐   ┌───────────────────────┐   ┌─────────────────┐
│    /data-entry    │   │       /reports        │   │    /settings    │
│                   │   │                       │   │                 │
│  📋 Bonuri List   │   │  📄 invoices [TABS]   │   │  ⚙️ Settings Hub │
│  📝 Bon Create    │   │  💰 bank-cash         │   │    (centralized │
│  ✏️ Bon Edit      │   │  🔢 trial-balance     │   │     settings)   │
│  📊 OCR Metrics   │   │  📉 maturity [TABS]   │   │                 │
│  ☁️ Bulk Upload   │   │  📋 detailed-invoices │   │  Links to:      │
│                   │   │  📈 cache-stats       │   │  - OCR Settings │
│  [FAB: +]         │   │  📝 server-logs       │   │  - Cache Stats  │
│  - Bon Nou        │   │  📱 telegram          │   │  - Server Logs  │
│  - Upload Bulk    │   │                       │   │  - Telegram     │
└───────────────────┘   └───────────────────────┘   └─────────────────┘

        /dashboard
           │
           ▼
┌─────────────────────┐
│  🏠 Dashboard       │  ← Primary entry point (Footer Nav)
│  SwipeableCards KPIs│
│  (No quick-links    │
│   on mobile)        │
└─────────────────────┘
```

> **Phase 3 Navigation Changes:**
> - `/dashboard` is now a direct route in Footer Nav (not under `/reports`)
> - Invoices and Maturity Analysis have Clienți/Furnizori tabs
> - FAB on Bonuri page provides Bon Nou + Upload Bulk actions

### Navigation Flow: Settings Hub Pattern

The Settings Hub (`/settings`) is the centralized entry point for all administrative pages:

```
MobileBottomNav "Setări" button
          │
          ▼
    ┌───────────────────────────────────┐
    │         Settings Hub              │
    │         /settings                 │
    │                                   │
    │  ┌─────────┐   ┌─────────┐       │
    │  │   OCR   │   │  Cache  │       │
    │  │ Setări  │   │  Stats  │       │
    │  └────┬────┘   └────┬────┘       │
    │       │             │            │
    │  ┌────┴────┐   ┌────┴────┐       │
    │  │ Server  │   │Telegram │       │
    │  │  Logs   │   │  Bot    │       │
    │  └─────────┘   └─────────┘       │
    └───────────────────────────────────┘
          │
          ▼ (click on card)
    ┌───────────────────────────────────┐
    │  /data-entry/ocr-metrics          │
    │  /reports/cache-stats             │
    │  /reports/server-logs             │
    │  /reports/telegram                │
    └───────────────────────────────────┘
```

### MobileBottomNav Default Items (Phase 3 - 4 Direct Links)

```javascript
// Default navigation items - Phase 3 (4 links, no action button)
[
  { to: '/dashboard', icon: 'pi pi-home', label: 'Dashboard' },
  { to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri' },
  { to: '/reports/invoices', icon: 'pi pi-file-edit', label: 'Facturi' },
  { to: '/settings', icon: 'pi pi-cog', label: 'Setări' }
]
```

> **Phase 3 Changes:**
> - Upload button removed from footer (moved to FAB on Bonuri page)
> - Dashboard added as direct link
> - Facturi added as direct link (with Clienți/Furnizori tabs)
> - All 4 items are now router links (no action buttons)

### MobileDrawerMenu Navigation Links (Phase 3 - Grouped Categories)

```javascript
// PRINCIPALE: Primary navigation
const principaleItems = [
  { to: '/dashboard', icon: 'pi pi-home', label: 'Dashboard', exactMatch: true },
  { to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri', exactMatch: false }
]

// RAPOARTE: Reports section
const rapoarteItems = [
  { to: '/reports/invoices', icon: 'pi pi-file', label: 'Facturi', exactMatch: true },
  { to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță', exactMatch: true },
  { to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Casa și Banca', exactMatch: true }
]

// ANALIZE: Analysis section
const analizeItems = [
  { to: '/reports/maturity-analysis', icon: 'pi pi-clock', label: 'Scadențe', exactMatch: true },
  { to: '/reports/detailed-invoices', icon: 'pi pi-list', label: 'Facturi Detaliate', exactMatch: true }
]

// ADMINISTRARE: Admin section
const administrareItems = [
  { to: '/settings', icon: 'pi pi-cog', label: 'Setări', exactMatch: false }
]
```

> **Phase 3 Changes:**
> - Navigation items organized into 4 visual sections with headers
> - Visual dividers between sections (`.drawer-divider`)
> - Section headers styled as uppercase labels (PRINCIPALE, RAPOARTE, ANALIZE, ADMINISTRARE)
> - `exactMatch` flag for precise active state highlighting

### Dashboard Mobile Layout (Phase 3 - KPIs Only)

On mobile, Dashboard shows ONLY KPI cards (quick-links removed in Phase 3):

```
┌─────────────────────────────────────────┐
│         MobileTopBar: Dashboard         │
│  [≡]       Dashboard         [📥] [🔍] │
├─────────────────────────────────────────┤
│                                         │
│  ┌─────────────────────────────────┐   │
│  │     SwipeableCards (KPIs)       │   │
│  │     ← Swipe →                   │   │
│  │                                 │   │
│  │   Total Facturi: 125,430 RON   │   │
│  │   Scadențe: 5 restante         │   │
│  │   ...                          │   │
│  │                                 │   │
│  └─────────────────────────────────┘   │
│                                         │
│           ●━━━━●───●                    │
│                                         │
│  (No quick-links on mobile - use       │
│   Footer Nav or Hamburger Menu)        │
│                                         │
├─────────────────────────────────────────┤
│        MobileBottomNav (56px)           │
│   🏠        📋       📄       ⚙️        │
│ Dashboard  Bonuri  Facturi  Setări      │
└─────────────────────────────────────────┘
```

> **Phase 3 Changes:**
> - Quick-link cards removed from mobile Dashboard
> - Desktop Dashboard keeps quick-links (unchanged)
> - Navigation to other pages via Footer Nav or Hamburger Menu

---

## MobileTopBar

Material Design 3 inspired top navigation bar for mobile views.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `title` | String | `''` | Center title text |
| `showBack` | Boolean | `false` | Show back arrow button on left |
| `showMenu` | Boolean | `false` | Show hamburger menu on left (ignored if showBack is true) |
| `actions` | Array | `[]` | Right-side action buttons |
| `selectionActive` | Boolean | `false` | Enable selection mode styling |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `menu-click` | - | Hamburger menu clicked |
| `back-click` | - | Back arrow clicked |
| `action-click` | `action` | Action button clicked |

### Action Object Structure

```typescript
interface TopBarAction {
  icon: string      // PrimeIcons class (e.g., 'pi pi-filter')
  label?: string    // Accessibility label
  tooltip?: string  // Tooltip text
  active?: boolean  // Highlight when active
}
```

### Basic Usage

```vue
<template>
  <MobileTopBar
    title="Bonuri Fiscale"
    :showMenu="true"
    :actions="topBarActions"
    @menu-click="showSidebar = true"
    @action-click="handleAction"
  />
</template>

<script setup>
const topBarActions = [
  { icon: 'pi pi-filter', label: 'Filtrează', tooltip: 'Deschide filtre' },
  { icon: 'pi pi-search', label: 'Caută', tooltip: 'Căutare' }
]

const handleAction = (action) => {
  if (action.icon === 'pi pi-filter') {
    openFilterSheet()
  }
}
</script>
```

### With Back Navigation

```vue
<MobileTopBar
  title="Detalii Bon"
  :showBack="true"
  @back-click="router.back()"
/>
```

### Selection Mode

```vue
<MobileTopBar
  :title="selectedCount > 0 ? `${selectedCount} selectate` : 'Bonuri'"
  :showBack="selectedCount > 0"
  :selectionActive="selectedCount > 0"
  :actions="selectionActions"
  @back-click="clearSelection"
/>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.mobile-top-bar` | Base container (fixed, 56px height) |
| `.selection-active` | Blue background for selection mode |
| `.top-bar-left` | Left button container |
| `.top-bar-right` | Right action buttons container |
| `.top-bar-title` | Center title (ellipsis on overflow) |
| `.top-bar-btn` | Individual button (48x48px touch target) |
| `.top-bar-btn.active` | Highlighted state |

---

## MobileBottomNav

Material Design 3 inspired bottom navigation bar with router integration.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `items` | Array | Default nav items | Navigation items array |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `item-click` | `item` | Non-router item clicked |

### Item Object Structure

```typescript
interface NavItem {
  to?: string       // Route path (uses router-link when provided)
  icon: string      // PrimeIcons class (e.g., 'pi pi-receipt')
  label: string     // Display text
  active?: boolean  // Force active state (for non-router items)
}
```

### Default Items

```javascript
[
  { to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri' },
  { icon: 'pi pi-cloud-upload', label: 'Upload' },  // Action button
  { to: '/reports/dashboard', icon: 'pi pi-chart-bar', label: 'Rapoarte' },
  { to: '/settings', icon: 'pi pi-cog', label: 'Setări' }  // → Settings Hub
]
```

### Basic Usage

```vue
<template>
  <MobileBottomNav />
</template>
```

### Custom Items

```vue
<template>
  <MobileBottomNav
    :items="customItems"
    @item-click="handleNavClick"
  />
</template>

<script setup>
const customItems = [
  { to: '/home', icon: 'pi pi-home', label: 'Acasă' },
  { to: '/reports', icon: 'pi pi-chart-bar', label: 'Rapoarte' },
  { icon: 'pi pi-plus', label: 'Adaugă' },  // Button, not route
  { to: '/settings', icon: 'pi pi-cog', label: 'Setări' }
]

const handleNavClick = (item) => {
  if (item.label === 'Adaugă') {
    showAddDialog()
  }
}
</script>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.mobile-bottom-nav` | Base container (fixed, 56px height) |
| `.bottom-nav-item` | Individual nav item (flex: 1) |
| `.bottom-nav-item.active` | Active state (primary color) |
| `.bottom-nav-item.router-link-active` | Auto-active via Vue Router |

---

## MobileDrawerMenu

*(UPDATED - Phase 3)*

Material Design 3 inspired navigation drawer that slides in from the left. Replaces the desktop sidebar on mobile devices. **Phase 3** reorganized navigation into grouped categories with visual separators.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `modelValue` | Boolean | `false` | Controls visibility (v-model support) |
| `user` | Object | `null` | User object for profile display `{ username: string }` |
| `onLogout` | Function | `null` | Optional logout callback; emits `logout` event if not provided |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `update:modelValue` | `boolean` | v-model update when visibility changes |
| `logout` | - | Emitted when logout is clicked (if no `onLogout` prop) |

### Navigation Items (Phase 3 - Grouped Categories)

The drawer navigation is organized into 4 sections with visual separators:

```javascript
// PRINCIPALE Section
const principaleItems = [
  { to: '/dashboard', icon: 'pi pi-home', label: 'Dashboard', exactMatch: true },
  { to: '/data-entry', icon: 'pi pi-receipt', label: 'Bonuri', exactMatch: false }
]

// RAPOARTE Section
const rapoarteItems = [
  { to: '/reports/invoices', icon: 'pi pi-file', label: 'Facturi', exactMatch: true },
  { to: '/reports/trial-balance', icon: 'pi pi-calculator', label: 'Balanță', exactMatch: true },
  { to: '/reports/bank-cash', icon: 'pi pi-money-bill', label: 'Casa și Banca', exactMatch: true }
]

// ANALIZE Section
const analizeItems = [
  { to: '/reports/maturity-analysis', icon: 'pi pi-clock', label: 'Scadențe', exactMatch: true },
  { to: '/reports/detailed-invoices', icon: 'pi pi-list', label: 'Facturi Detaliate', exactMatch: true }
]

// ADMINISTRARE Section
const administrareItems = [
  { to: '/settings', icon: 'pi pi-cog', label: 'Setări', exactMatch: false }
]
```

### Section Structure

```
┌──────────────────┐
│  🏢 ROA2WEB      │  ← Header with logo
├──────────────────┤
│  PRINCIPALE      │  ← Section header (uppercase)
│  🏠 Dashboard    │
│  📋 Bonuri       │
│  ──────────────  │  ← Divider
│  RAPOARTE        │
│  📄 Facturi      │
│  🔢 Balanță      │
│  💰 Casa și Banca│
│  ──────────────  │
│  ANALIZE         │
│  ⏰ Scadențe     │
│  📋 Facturi Det. │
│  ──────────────  │
│  ADMINISTRARE    │
│  ⚙️ Setări       │
├──────────────────┤
│  👤 Username     │  ← Profile section (footer)
│  🚪 Deconectare  │
└──────────────────┘
```

### Basic Usage

```vue
<template>
  <MobileTopBar
    title="Dashboard"
    :showMenu="true"
    @menu-click="showDrawer = true"
  />

  <MobileDrawerMenu
    v-model="showDrawer"
    :user="authStore.user"
    @logout="handleLogout"
  />
</template>

<script setup>
import { ref } from 'vue'
import MobileDrawerMenu from '@shared/components/mobile/MobileDrawerMenu.vue'
import { useAuthStore } from '@/stores/auth'

const showDrawer = ref(false)
const authStore = useAuthStore()

const handleLogout = async () => {
  await authStore.logout()
  router.push('/login')
}
</script>
```

### With Logout Callback

```vue
<MobileDrawerMenu
  v-model="showDrawer"
  :user="{ username: 'John Doe' }"
  :onLogout="async () => {
    await api.logout()
    router.push('/login')
  }"
/>
```

### Features

| Feature | Description |
|---------|-------------|
| **Slide Animation** | Slides in from left with overlay fade |
| **Close on Tap Outside** | Tapping the overlay closes the drawer |
| **Close on Navigation** | Drawer closes automatically when a link is clicked |
| **Active State** | Current route is highlighted |
| **Profile Section** | Displays username and logout button at bottom |
| **Teleported** | Rendered to `<body>` to avoid z-index issues |
| **Dark Mode** | Full support for light/dark themes |

### CSS Classes

| Class | Description |
|-------|-------------|
| `.drawer-overlay` | Full-screen backdrop (50% black, 70% in dark mode) |
| `.drawer-menu` | Main drawer container (280px, max 85vw) |
| `.drawer-header` | Header with logo |
| `.drawer-sections` | Scrollable container for all navigation sections |
| `.drawer-section` | Individual section container |
| `.section-header` | Section header label (PRINCIPALE, RAPOARTE, etc.) - uppercase, small text |
| `.drawer-nav` | List container for navigation links |
| `.drawer-link` | Individual navigation link (48px min-height) |
| `.drawer-link.active` | Active route styling (blue background) |
| `.drawer-divider` | Visual separator between sections |
| `.drawer-profile` | Profile section at bottom |
| `.profile-header` | User avatar and name row |
| `.profile-avatar` | Circular avatar with user icon |
| `.logout-link` | Red logout button styling |

### Section Header Styling

```css
.section-header {
  padding: var(--space-sm) var(--space-lg);
  font-size: var(--text-xs);
  font-weight: var(--font-semibold);
  color: var(--text-color-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.drawer-divider {
  height: 1px;
  background: var(--surface-border);
  margin: var(--space-xs) var(--space-md);
}
```

### Animation

Uses Vue `<Transition name="drawer">`:
- Overlay fades in/out
- Drawer slides from left (`translateX(-100%)` → `translateX(0)`)
- Duration: `var(--transition-normal)` (250ms)

---

## Mobile Tab Pattern

*(NEW - Phase 3)*

Material Design 3 inspired full-width tabs for switching between Clienți and Furnizori views. Used in pages that display partner-related data.

### When to Use

Use the Mobile Tab Pattern when:
- A page shows data that can be filtered by partner type (Clienți/Furnizori)
- The tab switch should be persistent via URL query parameter
- Both tabs share the same filters (except type)

### Implementation

```vue
<template>
  <!-- US-304/US-305: Mobile Tabs for Clienți/Furnizori -->
  <div v-if="isMobile" class="mobile-tabs-container">
    <div class="mobile-tabs">
      <button
        class="mobile-tab"
        :class="{ active: activeTab === 'clients' }"
        @click="switchTab('clients')"
      >
        <span class="tab-label">Clienți</span>
      </button>
      <button
        class="mobile-tab"
        :class="{ active: activeTab === 'suppliers' }"
        @click="switchTab('suppliers')"
      >
        <span class="tab-label">Furnizori</span>
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()

// Tab state synced with URL query param
const activeTab = ref(route.query.tab === 'suppliers' ? 'suppliers' : 'clients')

// Switch tab and update URL
const switchTab = (tab) => {
  if (tab === activeTab.value) return
  activeTab.value = tab

  // Update URL query param without full navigation
  router.replace({
    query: { ...route.query, tab: tab === 'clients' ? undefined : tab }
  })

  // Trigger data reload with new type
  loadData()
}
</script>
```

### CSS Classes

```css
/* Tab container - positioned below MobileTopBar */
.mobile-tabs-container {
  position: fixed;
  top: 56px; /* Below MobileTopBar */
  left: 0;
  right: 0;
  z-index: 999;
  background: var(--surface-card);
  border-bottom: 1px solid var(--surface-border);
}

.mobile-tabs {
  display: flex;
  width: 100%;
}

.mobile-tab {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md) var(--space-sm);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: all var(--transition-fast);
  color: var(--text-color-secondary);
  min-height: 48px;
  font-size: var(--text-base);
  font-weight: var(--font-medium);
}

.mobile-tab:active {
  background: var(--surface-hover);
}

.mobile-tab.active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
  font-weight: var(--font-semibold);
}
```

### Content Padding

When using tabs, increase top padding to account for both bars:

```css
.mobile-content-with-tabs {
  padding-top: 104px; /* 56px (TopBar) + 48px (Tabs) */
  padding-bottom: 56px; /* BottomNav */
}
```

### Used In

| Page | Route | Description |
|------|-------|-------------|
| **Facturi** | `/reports/invoices` | Switch between client/supplier invoices |
| **Scadențe** | `/reports/maturity-analysis` | Switch between client/supplier maturity |

---

## FAB Pattern

*(NEW - Phase 3)*

Material Design 3 inspired Floating Action Button (FAB) for contextual actions. Positioned above MobileBottomNav with popup menu support.

### When to Use

Use the FAB Pattern when:
- A page has primary actions that benefit from prominent placement
- Multiple related actions can be grouped (popup menu)
- Actions were previously in footer/header but need better mobile UX

### Design Tokens

```javascript
// From PRD cssRules.mobileLayoutTokens
{
  fabSize: '56px',           // FAB diameter
  fabBottomOffset: '72px',   // 56px (nav) + 16px spacing
  touchTargetMin: '48px'     // Minimum touch target
}
```

### Implementation

```vue
<template>
  <!-- FAB Button -->
  <Transition name="fab-slide">
    <button
      v-if="isMobile && !selectionMode && fabVisible"
      class="mobile-fab"
      :class="{ 'fab-active': fabMenuOpen }"
      @click="toggleFabMenu"
      aria-label="Meniu acțiuni"
      aria-haspopup="true"
      :aria-expanded="fabMenuOpen"
    >
      <i class="pi pi-plus" :class="{ 'fab-icon-rotate': fabMenuOpen }"></i>
    </button>
  </Transition>

  <!-- FAB Popup Menu -->
  <Menu
    ref="fabMenuRef"
    :model="fabMenuItems"
    :popup="true"
    class="fab-popup-menu"
  />
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import Menu from 'primevue/menu'

const router = useRouter()
const fabMenuRef = ref(null)
const fabMenuOpen = ref(false)
const fabVisible = ref(true)

// FAB Menu Items
const fabMenuItems = [
  {
    label: 'Bon Nou',
    icon: 'pi pi-plus',
    command: () => router.push('/data-entry/receipts/new')
  },
  {
    label: 'Upload Bulk',
    icon: 'pi pi-cloud-upload',
    command: () => openBulkUpload()
  }
]

// Toggle FAB Menu
const toggleFabMenu = (event) => {
  fabMenuOpen.value = !fabMenuOpen.value
  fabMenuRef.value?.toggle(event)
}

// Hide FAB during scroll, show when scroll stops
let lastScrollY = 0
const handleScroll = () => {
  const currentScrollY = window.scrollY
  const scrollDelta = currentScrollY - lastScrollY

  if (scrollDelta > 10) {
    fabVisible.value = false  // Scrolling down - hide
  } else if (scrollDelta < -10) {
    fabVisible.value = true   // Scrolling up - show
  }

  lastScrollY = currentScrollY

  // Show after scroll stops (300ms)
  clearTimeout(scrollTimeout)
  scrollTimeout = setTimeout(() => {
    fabVisible.value = true
  }, 300)
}
</script>
```

### CSS Classes

```css
/* FAB Button */
.mobile-fab {
  position: fixed;
  bottom: 72px; /* 56px nav + 16px spacing */
  right: var(--space-md);
  width: 56px;
  height: 56px;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: white;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  z-index: 999;
  transition: all var(--transition-fast);
}

.mobile-fab:active {
  transform: scale(0.95);
  box-shadow: var(--shadow-md);
}

.mobile-fab i {
  font-size: var(--text-2xl);
  transition: transform var(--transition-fast);
}

/* FAB active state when menu open */
.mobile-fab.fab-active {
  background: var(--color-primary-dark);
}

.mobile-fab .fab-icon-rotate {
  transform: rotate(45deg);
}

/* FAB Popup Menu positioning */
.fab-popup-menu {
  position: fixed !important;
  bottom: 140px !important; /* 72px + 56px + 12px */
  right: var(--space-md) !important;
  left: auto !important;
  top: auto !important;
  min-width: 180px;
  z-index: 1000 !important;
}

/* FAB slide animation */
.fab-slide-enter-active,
.fab-slide-leave-active {
  transition: transform var(--transition-normal), opacity var(--transition-normal);
}

.fab-slide-enter-from,
.fab-slide-leave-to {
  transform: translateY(100px);
  opacity: 0;
}
```

### Behavior

| Interaction | Result |
|-------------|--------|
| **Tap FAB** | Opens popup menu with actions |
| **Tap menu item** | Executes action, closes menu |
| **Tap outside** | Closes menu |
| **Scroll down** | FAB hides (slide down) |
| **Scroll up** | FAB shows (slide up) |
| **Scroll stops** | FAB reappears after 300ms |
| **Selection mode** | FAB hidden (replaced by selection footer) |

### Used In

| Page | Route | Actions |
|------|-------|---------|
| **Bonuri** | `/data-entry` | Bon Nou, Upload Bulk |

> **Phase 3 Note:** Upload was moved from Footer Nav to FAB to reduce footer clutter and provide better contextual placement.

---

## MobileActionBar

Context-aware bottom action bar for forms and edit views. Positions above MobileBottomNav and displays action buttons based on current state.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `visible` | Boolean | `false` | Controls visibility (triggers slide-up animation) |
| `actions` | Array | `[]` | Array of action buttons to display |

### Action Object Structure

```typescript
interface ActionBarAction {
  label: string          // Button text (e.g., 'Salvează')
  icon: string           // PrimeIcons class (e.g., 'pi pi-save')
  severity?: string      // PrimeVue severity ('primary', 'secondary', 'danger', etc.)
  handler: () => void    // Click handler function
  disabled?: boolean     // Disable the button
}
```

### Layout Behavior

| Actions Count | Layout |
|---------------|--------|
| 1 button | Full-width |
| 2 buttons | Side-by-side, equal width |
| 3+ buttons | Equal distribution |

### Basic Usage

```vue
<template>
  <MobileActionBar
    :visible="isMobile"
    :actions="formActions"
  />
</template>

<script setup>
import MobileActionBar from '@shared/components/mobile/MobileActionBar.vue'

const formActions = [
  {
    label: 'Salvează',
    icon: 'pi pi-save',
    severity: 'primary',
    handler: handleSave
  },
  {
    label: 'Anulează',
    icon: 'pi pi-times',
    severity: 'secondary',
    handler: handleCancel
  }
]
</script>
```

### Context-Aware Actions (Receipt Edit Example)

```vue
<template>
  <MobileActionBar
    :visible="isMobile"
    :actions="contextAwareActions"
  />
</template>

<script setup>
import { computed } from 'vue'

const receiptStatus = ref('draft') // 'draft' | 'pending' | 'approved' | 'rejected'

const contextAwareActions = computed(() => {
  switch (receiptStatus.value) {
    case 'draft':
      return [
        { label: 'Salvează', icon: 'pi pi-save', severity: 'secondary', handler: handleSave },
        { label: 'Trimite', icon: 'pi pi-send', severity: 'primary', handler: handleSubmit }
      ]
    case 'pending':
      return [
        { label: 'Salvează', icon: 'pi pi-save', severity: 'secondary', handler: handleSave },
        { label: 'Aprobă', icon: 'pi pi-check', severity: 'success', handler: handleApprove },
        { label: 'Respinge', icon: 'pi pi-times', severity: 'danger', handler: handleReject }
      ]
    case 'approved':
      return [] // No actions for approved receipts
    case 'rejected':
      return [
        { label: 'Salvează', icon: 'pi pi-save', severity: 'secondary', handler: handleSave },
        { label: 'Re-trimite', icon: 'pi pi-refresh', severity: 'primary', handler: handleResubmit }
      ]
    default:
      return []
  }
})
</script>
```

### Hiding During Overlays

Hide the action bar when BottomSheet or other overlays are open:

```vue
<template>
  <MobileActionBar
    :visible="isMobile && !isBottomSheetOpen"
    :actions="formActions"
  />

  <BottomSheet v-model="isBottomSheetOpen">
    <!-- Filter content -->
  </BottomSheet>
</template>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.mobile-action-bar` | Base container (fixed, bottom: 56px) |
| `.action-bar-content` | Button container (max-width: 500px) |
| `.layout-single` | Single button layout (full-width) |
| `.layout-dual` | Two button layout (50% each) |
| `.layout-multi` | Three+ button layout (equal distribution) |
| `.action-bar-btn` | Individual button (48px min-height) |

### Animation

Uses Vue `<Transition name="slide-up">`:
- Slides up from below screen (`translateY(100%)` → `translateY(0)`)
- Duration: `var(--transition-normal)` (250ms)
- Fades in/out simultaneously

### Positioning

```css
.mobile-action-bar {
  position: fixed;
  bottom: 56px; /* Above MobileBottomNav */
  left: 0;
  right: 0;
  /* Safe area support for iPhone X+ */
  bottom: calc(56px + env(safe-area-inset-bottom));
}
```

### Content Padding Adjustment

When MobileActionBar is visible, increase bottom padding:

```css
.mobile-content {
  padding-bottom: 120px; /* 56px (nav) + 64px (action bar) */
}
```

---

## MobileSelectionFooter

Slide-up action bar for batch operations on selected items.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `visible` | Boolean | `false` | Controls visibility (triggers animation) |
| `actions` | Array | `[]` | Action buttons to display |

### Action Object Structure

```typescript
interface SelectionAction {
  label: string           // Button text
  icon: string            // PrimeIcons class
  severity?: string       // PrimeVue severity ('secondary', 'danger', etc.)
  handler: () => void     // Click handler function
}
```

### Basic Usage

```vue
<template>
  <MobileSelectionFooter
    :visible="selectedItems.length > 0"
    :actions="selectionActions"
  />
</template>

<script setup>
const selectedItems = ref([])

const selectionActions = computed(() => [
  {
    label: 'Șterge',
    icon: 'pi pi-trash',
    severity: 'danger',
    handler: deleteSelected
  },
  {
    label: 'Export',
    icon: 'pi pi-download',
    severity: 'secondary',
    handler: exportSelected
  }
])

const deleteSelected = () => {
  // Delete logic
  selectedItems.value = []
}

const exportSelected = () => {
  // Export logic
}
</script>
```

### Single Action

```vue
<MobileSelectionFooter
  :visible="hasSelection"
  :actions="[
    { label: 'Confirmă Selectate', icon: 'pi pi-check', severity: 'success', handler: confirmAll }
  ]"
/>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.mobile-selection-footer` | Base container (fixed, z-index 1030) |
| `.selection-actions` | Button container (max-width: 400px) |
| `.selection-action-btn` | Individual button (48px min-height) |

### Animation

Uses Vue `<Transition name="slide-up">`:
- Slides up from bottom when `visible` becomes `true`
- Slides down when `visible` becomes `false`
- Duration: `var(--transition-normal)` (250ms)

---

## BottomSheet

Modal-style sheet that slides up from the bottom, ideal for filters and forms.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `modelValue` | Boolean | `false` | v-model for visibility |
| `closeOnOverlay` | Boolean | `true` | Close when tapping overlay |
| `closeOnSwipeDown` | Boolean | `true` | Close when swiping down on handle |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `update:modelValue` | `boolean` | v-model update |

### Slots

| Slot | Description |
|------|-------------|
| `default` | Content inside the sheet |

### Basic Usage

```vue
<template>
  <Button label="Open Filters" @click="showFilters = true" />

  <BottomSheet v-model="showFilters">
    <h3>Filtre</h3>

    <div class="form-group">
      <label class="form-label">Status</label>
      <Dropdown v-model="filters.status" :options="statusOptions" />
    </div>

    <div class="form-group">
      <label class="form-label">Data</label>
      <Calendar v-model="filters.date" />
    </div>

    <div class="flex gap-sm mt-md">
      <Button label="Resetează" severity="secondary" @click="resetFilters" />
      <Button label="Aplică" @click="applyFilters" />
    </div>
  </BottomSheet>
</template>

<script setup>
const showFilters = ref(false)

const applyFilters = () => {
  // Apply filter logic
  showFilters.value = false
}
</script>
```

### Prevent Close on Overlay

```vue
<BottomSheet
  v-model="showImportantForm"
  :closeOnOverlay="false"
>
  <!-- User must explicitly close this -->
</BottomSheet>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.bottom-sheet-overlay` | Full-screen overlay (50% opacity black) |
| `.bottom-sheet` | Sheet container (max-height: 90vh) |
| `.bottom-sheet-handle` | Handle area at top (32px min-height) |
| `.handle-bar` | Visual drag indicator (40px × 4px) |
| `.bottom-sheet-content` | Scrollable content area |

### Touch Gestures

| Gesture | Action |
|---------|--------|
| Tap overlay | Close (if `closeOnOverlay: true`) |
| Tap handle | Close |
| Swipe down > 100px | Close (if `closeOnSwipeDown: true`) |

---

## SwipeableCards

Touch-swipeable carousel for KPI cards with dots indicator.

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `totalCards` | Number | **required** | Number of cards in carousel |
| `showDots` | Boolean | `true` | Show navigation dots |
| `autoPlay` | Boolean | `false` | Auto-advance cards |
| `autoPlayInterval` | Number | `5000` | Auto-play interval (ms) |

### Events

| Event | Payload | Description |
|-------|---------|-------------|
| `update:currentIndex` | `number` | Current card index changed |

### Slots

Named slots for each card: `card-0`, `card-1`, `card-2`, etc.

### Exposed Methods

| Method | Description |
|--------|-------------|
| `goToCard(index)` | Navigate to specific card |
| `nextCard()` | Go to next card |
| `prevCard()` | Go to previous card |
| `currentIndex` | Current card index (ref) |

### Basic Usage

```vue
<template>
  <SwipeableCards :totalCards="3">
    <template #card-0>
      <div class="kpi-card">
        <div class="kpi-value">$125,430</div>
        <div class="kpi-label">Total Sales</div>
      </div>
    </template>

    <template #card-1>
      <div class="kpi-card">
        <div class="kpi-value">1,234</div>
        <div class="kpi-label">Orders</div>
      </div>
    </template>

    <template #card-2>
      <div class="kpi-card">
        <div class="kpi-value">98.5%</div>
        <div class="kpi-label">Success Rate</div>
      </div>
    </template>
  </SwipeableCards>
</template>
```

### With Auto-Play

```vue
<SwipeableCards
  :totalCards="4"
  :autoPlay="true"
  :autoPlayInterval="3000"
>
  <!-- Cards -->
</SwipeableCards>
```

### Programmatic Navigation

```vue
<template>
  <SwipeableCards ref="carousel" :totalCards="3">
    <!-- Cards -->
  </SwipeableCards>

  <Button label="Next" @click="carousel.nextCard()" />
</template>

<script setup>
const carousel = ref(null)
</script>
```

### CSS Classes

| Class | Description |
|-------|-------------|
| `.swipeable-cards-container` | Base container with overflow hidden |
| `.cards-track` | Horizontal flex container (will-change: transform) |
| `.card-slide` | Individual card (flex: 0 0 100%) |
| `.dots-indicator` | Navigation dots container |
| `.dot` | Individual dot (8px, expands to 24px when active) |
| `.dot.active` | Active dot (primary color) |

### Touch Thresholds

| Threshold | Value | Description |
|-----------|-------|-------------|
| Swipe distance | 50px | Minimum swipe to change card |
| Velocity | 0.3 | Quick swipe detection |
| Angle | 30° | Max angle for horizontal detection |

---

## Design Tokens for Mobile

### Layout Tokens

| Token | Value | Use |
|-------|-------|-----|
| `--header-height` | 56px | MobileTopBar & MobileBottomNav height |
| `--z-fixed` | 1030 | Fixed elements z-index |
| `--z-modal-backdrop` | 1040 | BottomSheet overlay |
| `--z-modal` | 1050 | BottomSheet content |

### Touch Target Sizes

```css
/* Minimum touch target: 48x48px */
.touch-target {
  min-width: 48px;
  min-height: 48px;
}

/* Button in top bar */
.top-bar-btn {
  width: 48px;
  height: 48px;
}
```

### Spacing for Mobile

| Token | Value | Mobile Use |
|-------|-------|------------|
| `var(--space-xs)` | 4px | Icon gaps, tight spacing |
| `var(--space-sm)` | 8px | Between nav items, card gaps |
| `var(--space-md)` | 16px | Card padding, content margins |
| `var(--space-lg)` | 24px | Section spacing |

### Mobile Content Padding

```css
/* Standard mobile content area */
.mobile-content {
  padding-top: 56px;    /* MobileTopBar */
  padding-bottom: 56px; /* MobileBottomNav */
  padding-left: var(--space-md);
  padding-right: var(--space-md);
}

/* When selection footer is visible */
.mobile-content-with-selection {
  padding-bottom: 80px; /* Higher for selection footer */
}
```

---

## Best Practices

### 1. Always Use Design Tokens

```css
/* ✅ CORRECT */
.mobile-card {
  padding: var(--space-md);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

/* ❌ WRONG */
.mobile-card {
  padding: 16px;
  border-radius: 8px;
  box-shadow: 0 1px 2px rgba(0,0,0,0.05);
}
```

### 2. Account for Fixed Headers/Footers

```vue
<template>
  <div class="view-container">
    <MobileTopBar title="My View" />

    <main class="view-content">
      <!-- Content that scrolls -->
    </main>

    <MobileBottomNav />
  </div>
</template>

<style scoped>
.view-content {
  padding-top: 56px;    /* TopBar height */
  padding-bottom: 56px; /* BottomNav height */
  min-height: 100vh;
  overflow-y: auto;
}
</style>
```

### 3. Test Both Light and Dark Mode

All mobile components support:
- Manual dark mode: `[data-theme="dark"]`
- System preference: `@media (prefers-color-scheme: dark)`

```javascript
// Toggle theme in DevTools:
document.documentElement.setAttribute('data-theme', 'dark')
```

### 4. Handle Safe Areas (Notch/Home Indicator)

```css
.mobile-bottom-nav {
  padding-bottom: env(safe-area-inset-bottom);
}

.mobile-content {
  padding-bottom: calc(56px + env(safe-area-inset-bottom));
}
```

### 5. Selection Mode Pattern

```vue
<script setup>
const selectedItems = ref([])
const isSelectionMode = computed(() => selectedItems.value.length > 0)

const toggleSelection = (item) => {
  const index = selectedItems.value.findIndex(i => i.id === item.id)
  if (index === -1) {
    selectedItems.value.push(item)
  } else {
    selectedItems.value.splice(index, 1)
  }
}

const clearSelection = () => {
  selectedItems.value = []
}
</script>
```

### 6. Combine Components for Complex Views

```vue
<template>
  <!-- Top Bar adapts to selection mode -->
  <MobileTopBar
    :title="isSelectionMode ? `${selectedCount} selectate` : 'Bonuri'"
    :showBack="isSelectionMode"
    :selectionActive="isSelectionMode"
    :actions="currentActions"
    @back-click="clearSelection"
    @action-click="handleAction"
  />

  <!-- Main Content -->
  <main class="content">
    <SwipeableCards :totalCards="kpis.length">
      <template v-for="(kpi, i) in kpis" #[`card-${i}`]>
        <KPICard :data="kpi" />
      </template>
    </SwipeableCards>

    <ItemList :items="items" @select="toggleSelection" />
  </main>

  <!-- Bottom Nav (hidden in selection mode) -->
  <MobileBottomNav v-if="!isSelectionMode" />

  <!-- Selection Footer (shown in selection mode) -->
  <MobileSelectionFooter
    :visible="isSelectionMode"
    :actions="selectionActions"
  />

  <!-- Filter Sheet -->
  <BottomSheet v-model="showFilters">
    <FilterForm @apply="applyFilters" />
  </BottomSheet>
</template>
```

---

## Troubleshooting

### Top/Bottom bars not fixed

**Problem**: Bars scroll with content.

**Solution**: Ensure `.mobile-top-bar` and `.mobile-bottom-nav` have `position: fixed`. Check for `overflow: hidden` on ancestors.

### Content hidden behind bars

**Problem**: Content is cut off at top/bottom.

**Solution**: Add padding to content area:
```css
.content {
  padding-top: 56px;
  padding-bottom: 56px;
}
```

### BottomSheet z-index issues

**Problem**: BottomSheet appears behind other elements.

**Solution**: BottomSheet uses `<Teleport to="body">` to avoid stacking context issues. Check for `z-index` wars in your CSS.

### Swipe conflicts with scrolling

**Problem**: SwipeableCards interferes with vertical scroll.

**Solution**: Component uses angle detection (30° threshold). Ensure cards have sufficient content area. Check `touch-action: pan-y` is set.

### Dark mode not working

**Problem**: Components don't respond to theme changes.

**Solution**: All components support both mechanisms:
1. Manual: `[data-theme="dark"]` on `<html>`
2. System: `@media (prefers-color-scheme: dark)`

Check that `data-theme` attribute is set correctly.

### Selection footer overlaps content

**Problem**: When selection footer appears, it covers list items.

**Solution**: Use dynamic padding:
```css
.content {
  padding-bottom: v-bind(isSelectionMode ? '96px' : '56px');
}
```

---

## Related Documentation

- [Design Tokens](./DESIGN_TOKENS.md) - Color, spacing, typography tokens
- [CSS Patterns](./CSS_PATTERNS.md) - General UI patterns
- [Onboarding CSS](./ONBOARDING_CSS.md) - Quick start for CSS

---

## Changelog

### Version 3.0.0 (2026-01-12) - Phase 3: Mobile Navigation Overhaul

- **NEW**: Added `Mobile Tab Pattern` section for Clienți/Furnizori switching (US-304, US-305)
- **NEW**: Added `FAB Pattern` section for contextual actions (US-303)
- **UPDATED**: `MobileBottomNav` - 4 direct links: Dashboard, Bonuri, Facturi, Setări (US-307)
- **UPDATED**: `MobileDrawerMenu` - Grouped categories: PRINCIPALE, RAPOARTE, ANALIZE, ADMINISTRARE (US-308)
- **UPDATED**: Dashboard mobile layout - KPIs only, quick-links removed (US-309)
- **UPDATED**: ASCII diagrams with new navigation structure and FAB/Tab patterns
- **UPDATED**: Navigation Architecture with Phase 3 route map
- **REMOVED**: Upload button from footer nav (moved to FAB on Bonuri page)

### Version 2.0.0 (2026-01-12)

- **NEW**: Added `MobileDrawerMenu` component documentation
- **NEW**: Added `MobileActionBar` component documentation
- **NEW**: Added Navigation Architecture section with route maps
- **UPDATED**: MobileBottomNav default items now point to Settings Hub (`/settings`)
- **UPDATED**: ASCII diagrams with new routes and component layouts
- **UPDATED**: Quick Start section to include drawer menu integration

### Version 1.0.0 (2026-01-11)

- Initial release with MobileTopBar, MobileBottomNav, MobileSelectionFooter, BottomSheet, SwipeableCards

---

**Last Updated:** 2026-01-12
**Version:** 3.0.0
**Maintained By:** Frontend Team
