# Mobile-Responsive Implementation Guide

## Overview

This document describes the mobile-responsive updates implemented for the CPAS Tracker application. The design targets **standard phones (375px+ width)** with graceful degradation for smaller devices.

## Key Changes

### 1. **Responsive Utility Stylesheet** (`client/src/styles/mobile.css`)

A centralized CSS file providing:
- Media query breakpoints (768px, 480px)
- Touch-friendly tap targets (min 44px height)
- iOS input zoom prevention (16px font size)
- Utility classes for mobile layouts
- Card-based layout helpers
- Horizontal scroll containers

**Utility Classes:**
- `.hide-mobile` - Hide on screens ≤768px
- `.hide-tablet` - Hide on screens ≤1024px  
- `.mobile-full-width` - Full width on mobile
- `.mobile-stack` - Stack flex items vertically
- `.mobile-scroll-x` - Enable horizontal scrolling
- `.mobile-card` - Card layout container
- `.mobile-sticky-top` - Sticky header positioning

### 2. **App Navigation** (`client/src/App.jsx`)

**Desktop Behavior:**
- Horizontal navigation bar
- Logo left, tabs center, docs button right
- Full tab labels displayed

**Mobile Behavior (768px):**
- Logo centered with full width
- Tabs stacked horizontally below logo
- Docs button positioned absolutely top-right
- Shortened tab labels ("📊 Dashboard" → "📊")
- Flexible padding (40px → 16px)

**Features:**
- `useMediaQuery()` hook for responsive detection
- Dynamic style injection via `<style>` tag
- Separate mobile CSS classes for targeted overrides

### 3. **Dashboard Layout** (`client/src/components/Dashboard.jsx`)

**Desktop View:**
- Traditional HTML table layout
- 7 columns (Index, Employee, Dept, Supervisor, Tier, Points, Violations)
- Horizontal scrolling for overflow

**Mobile View (768px):**
- Switches to card-based layout (DashboardMobile component)
- Each employee = one card with vertical data rows
- Touch-optimized tap targets
- Improved readability with larger fonts

**Mobile Stat Cards:**
- 2 columns on phones (480px+)
- 1 column on small phones (<480px)
- Reduced font sizes (28px → 24px)
- Compact padding

**Toolbar Adjustments:**
- Search input: 260px → 100% width
- Buttons stack vertically
- Full-width button styling

### 4. **Mobile Dashboard Component** (`client/src/components/DashboardMobile.jsx`)

A dedicated mobile-optimized employee card component:

**Card Structure:**
```
+--------------------------------+
| Employee Name [Button]         |
| [At Risk Badge if applicable]  |
|--------------------------------|
| Tier / Standing: [Badge]       |
| Active Points: [Large #]       |
| 90-Day Violations: [#]         |
| Department: [Name]             |
| Supervisor: [Name]             |
+--------------------------------+
```

**Visual Features:**
- At-risk employees: Gold border + dark gold background
- Touch-friendly employee name buttons
- Color-coded point displays matching tier colors
- Compact spacing (12px margins)
- Subtle shadows for depth

### 5. **Responsive Breakpoints**

| Breakpoint | Target Devices | Layout Changes |
|------------|----------------|----------------|
| **1024px** | Tablets & below | Reduced padding, simplified nav |
| **768px**  | Phones (landscape) | Card layouts, stacked navigation |
| **480px**  | Small phones | Single-column stats, minimal spacing |
| **375px**  | iPhone SE/6/7/8 | Optimized for minimum supported width |

### 6. **Touch Optimization**

**Tap Target Sizes:**
- All buttons: 44px minimum height (iOS/Android guidelines)
- Form inputs: 44px minimum height
- Navigation tabs: 44px touch area

**Typography:**
- Form inputs: 16px font size (prevents iOS zoom-in on focus)
- Readable body text: 13-14px
- Headers scale down appropriately

**Scrolling:**
- `-webkit-overflow-scrolling: touch` for smooth momentum scrolling
- Horizontal scroll on tables (desktop fallback)
- Vertical card scrolling on mobile

## Implementation Details

### Media Query Hook

```javascript
function useMediaQuery(query) {
  const [matches, setMatches] = useState(false);
  useEffect(() => {
    const media = window.matchMedia(query);
    if (media.matches !== matches) setMatches(media.matches);
    const listener = () => setMatches(media.matches);
    media.addEventListener('change', listener);
    return () => media.removeEventListener('change', listener);
  }, [matches, query]);
  return matches;
}
```

**Usage:**
```javascript
const isMobile = useMediaQuery('(max-width: 768px)');
```

### Conditional Rendering Pattern

```javascript
{isMobile ? (
  <DashboardMobile employees={filtered} onEmployeeClick={setSelectedId} />
) : (
  <table style={s.table}>
    {/* Desktop table layout */}
  </table>
)}
```

### Dynamic Style Injection

```javascript
const mobileStyles = `
  @media (max-width: 768px) {
    .dashboard-wrap {
      padding: 16px !important;
    }
  }
`;

return (
  <>
    <style>{mobileStyles}</style>
    {/* Component JSX */}
  </>
);
```

## Testing Checklist

### Desktop (>768px)
- [ ] Navigation displays horizontally
- [ ] Dashboard shows full table
- [ ] All columns visible
- [ ] Docs button on right side
- [ ] Full tab labels visible

### Tablet (768px - 1024px)
- [ ] Reduced padding maintains readability
- [ ] Stats cards wrap to 2-3 columns
- [ ] Table scrolls horizontally if needed

### Mobile Portrait (375px - 768px)
- [ ] Logo centered, tabs stacked
- [ ] Dashboard shows card layout
- [ ] Search input full width
- [ ] Buttons stack vertically
- [ ] Employee cards display all data
- [ ] Tap targets ≥44px
- [ ] No horizontal scroll required

### Small Mobile (<480px)
- [ ] Stat cards single column
- [ ] Text remains readable
- [ ] No layout breakage
- [ ] Footer wraps properly

### iOS-Specific
- [ ] Input focus doesn't zoom page (16px font)
- [ ] Smooth momentum scrolling
- [ ] Tap highlights work correctly

### Android-Specific
- [ ] Touch feedback visible
- [ ] Back button behavior correct
- [ ] Keyboard doesn't break layout

## Browser Support

- **Chrome/Edge:** 88+
- **Firefox:** 85+
- **Safari:** 14+
- **iOS Safari:** 14+
- **Chrome Android:** 88+

## Performance Considerations

1. **Media query hook** re-renders only on breakpoint changes, not continuous resize
2. **Card layout** renders fewer DOM elements than table on mobile
3. **CSS injection** happens once per component mount
4. **No external CSS libraries** (zero KB bundle increase)

## Future Enhancements

### Phase 2 (Optional)
- [ ] ViolationForm mobile optimization with multi-step wizard
- [ ] Modal responsive sizing and animations
- [ ] Swipe gestures for employee cards
- [ ] Pull-to-refresh on mobile
- [ ] Offline support with service workers

### Phase 3 (Advanced)
- [ ] Progressive Web App (PWA) capabilities
- [ ] Native app shell with Capacitor
- [ ] Biometric authentication
- [ ] Push notifications

## File Structure

```
client/src/
├── App.jsx                    # Updated with mobile nav
├── components/
│   ├── Dashboard.jsx           # Responsive table/card switch
│   ├── DashboardMobile.jsx     # Mobile card layout (NEW)
│   └── ...                     # Other components
└── styles/
    └── mobile.css              # Responsive utilities (NEW)
```

## Maintenance Notes

### Adding New Components

When creating new components, follow this pattern:

1. **Import mobile.css utility classes:**
   ```javascript
   import '../styles/mobile.css';
   ```

2. **Use media query hook:**
   ```javascript
   const isMobile = useMediaQuery('(max-width: 768px)');
   ```

3. **Provide mobile-specific styles:**
   ```javascript
   const mobileStyles = `
     @media (max-width: 768px) {
       .my-component { /* mobile overrides */ }
     }
   `;
   ```

4. **Test on real devices** (Chrome DevTools is insufficient for touch testing)

### Debugging Tips

- Use Chrome DevTools Device Mode (Ctrl+Shift+M)
- Test on actual devices when possible
- Check console for media query match state
- Verify tap target sizes with Chrome Lighthouse audit
- Test keyboard behavior on Android

## Deployment

1. Merge `feature/mobile-responsive` into `master`
2. Rebuild client bundle: `cd client && npm run build`
3. Restart server
4. Clear browser cache (Ctrl+Shift+R)
5. Test on production URL with mobile devices

## Support

For issues or questions about mobile-responsive implementation:
- Check browser console for errors
- Verify `mobile.css` is loaded
- Test with different screen sizes
- Review media query breakpoints

---

**Branch:** `feature/mobile-responsive`  
**Target Width:** 375px+ (standard phones)  
**Last Updated:** March 8, 2026  
**Maintainer:** Jason Stedwell
