# Product Requirements Document

## Validation Checklist

- [x] All required sections are complete
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Problem statement is specific and measurable
- [x] Problem is validated by evidence (user research section)
- [x] Context → Problem → Solution flow makes sense
- [x] Every persona has at least one user journey
- [x] All MoSCoW categories addressed (Must/Should/Could/Won't)
- [x] Every feature has testable acceptance criteria
- [x] Every metric has corresponding tracking events
- [x] No feature redundancy (check for duplicates)
- [x] No contradictions between sections
- [x] No technical implementation details included
- [x] A new team member could understand this PRD

---

## Product Overview

### Vision
Enable seamless real-time team communication within BuyerKiosk apps, replacing third-party tools (Slack, WhatsApp groups) with a built-in chat experience that understands store context and integrates with scheduling, tasks, and shift management.

### Problem Statement
Store teams currently rely on fragmented communication channels:
- Personal WhatsApp groups mix work and personal messages
- Slack/Discord require separate app switching
- No integration with scheduling context (who's working when)
- Managers can't reach all staff through official channels
- No visibility into whether messages were read
- External tools don't understand store hierarchy/roles

**Cost of Status Quo (estimated from user feedback):**
- ~15% of shift-related messages are missed or delayed due to app fragmentation
- Managers spend ~30 min/day coordinating across multiple platforms
- No audit trail for HR disputes or compliance investigations
- Staff turnover is partially attributed to communication friction

### Value Proposition
- **Single app experience**: No app-switching for team communication
- **Store-aware**: Channels scoped to stores, role-based access
- **Scheduling integration**: See who's on shift, @mention by role
- **Official record**: Auditable communication for HR/compliance
- **Real-time**: Instant delivery with typing indicators and read receipts

## User Personas

### Primary Persona: Team Member (Staff/Employee)
- **Demographics:** 18-35, hourly retail/restaurant worker, moderate smartphone proficiency
- **Goals:** Quick communication with coworkers, get shift updates, request swaps
- **Pain Points:** Too many apps to check, miss important messages, can't reach manager quickly

### Secondary Persona: Shift Manager
- **Demographics:** 25-45, supervisory role, high smartphone proficiency
- **Goals:** Broadcast announcements, coordinate coverage, respond to issues quickly
- **Pain Points:** Can't confirm staff saw messages, no central channel for store updates

### Tertiary Persona: Store Owner/GM
- **Demographics:** 30-55, business owner, moderate tech proficiency
- **Goals:** Monitor store communication, make announcements, ensure policy compliance
- **Pain Points:** No visibility into team communication, reliance on personal messaging

## User Journey Maps

### Primary User Journey: Quick Team Message
1. **Awareness:** User receives push notification of new message
2. **Consideration:** Sees message preview in notification
3. **Adoption:** Taps notification, app opens to conversation
4. **Usage:** Reads message, taps to reply, sends response
5. **Retention:** Gets immediate delivery confirmation, sees read receipts

### Secondary User Journey: @Mention Response
1. **Trigger:** User is mentioned in a channel message
2. **Discovery:** Receives push notification with mention preview
3. **Action:** Navigates to mentions inbox or directly to message
4. **Response:** Replies in thread or reacts with emoji
5. **Completion:** Mention marked as read

### Tertiary User Journey: Broadcast Announcement
1. **Need:** Manager needs to communicate policy change
2. **Compose:** Opens channel, types message, optionally @mentions roles
3. **Send:** Sends message to store channel
4. **Monitor:** Checks read receipts to see who viewed
5. **Follow-up:** Can resend or personally message those who haven't read

## Feature Requirements

### Must Have Features

#### Feature 1: Channel List View
- **User Story:** As a team member, I want to see all my channels so that I can quickly access conversations
- **Acceptance Criteria:**
  - [ ] Display all accessible channels based on user's role
  - [ ] Show unread message count badge per channel
  - [ ] Show last message preview (truncated) and timestamp
  - [ ] Indicate muted channels visually (mute icon)
  - [ ] **Organization:** Pinned channels at top (manual pin via long-press), then sorted by most recent activity
  - [ ] Include "Mentions" tab alongside channels list for @mention inbox
  - [ ] Support pull-to-refresh to reload channel list

#### Feature 2: Message Viewing
- **User Story:** As a team member, I want to read messages in a channel so that I stay informed
- **Acceptance Criteria:**
  - [ ] Display messages in chronological order (newest at bottom)
  - [ ] **Bubble Style:** WhatsApp-style - own messages right-aligned (brand purple #7c3aed), others left-aligned (gray/white)
  - [ ] **Avatars:** Show avatar only for first message in consecutive group from same sender
  - [ ] **Timestamps:** Group timestamps as section headers (e.g., "Today 2:30 PM"), not on every message
  - [ ] Support infinite scroll pagination (load older messages on scroll up)
  - [ ] Mark messages as read automatically when scrolled into view
  - [ ] **System messages:** Centered gray italic text, no bubble (e.g., "John joined the channel")
  - [ ] **Skeleton loaders** while loading messages
  - [ ] **Floating "Jump to new" button** when scrolled up with unread messages below

#### Feature 3: Send Messages
- **User Story:** As a team member, I want to send messages so that I can communicate with my team
- **Acceptance Criteria:**
  - [ ] **Input bar layout:** Attachment button (camera/gallery) | Text field | Emoji button | Send arrow
  - [ ] Support @mentions with **dropdown autocomplete above keyboard** showing avatars and names
  - [ ] Show sending/sent/failed status with **inline error + retry button** on failure
  - [ ] Respect rate limits gracefully (30 msgs/min) with user-friendly message
  - [ ] **Swipe gestures:** Swipe right on message to react, swipe left to reply
  - [ ] **Read-only offline mode:** Cannot compose when offline, show cached messages only

#### Feature 4: Emoji Reactions
- **User Story:** As a team member, I want to react with emojis so that I can quickly acknowledge messages
- **Acceptance Criteria:**
  - [ ] Add reaction to any message via swipe right or long-press
  - [ ] **Reaction picker:** Quick bar with 6 common emojis + "more" button for full emoji keyboard
  - [ ] **Reaction display:** Chips below message bubble showing emoji + count, tappable to see who reacted
  - [ ] Tap own reaction to remove it
  - [ ] Limit of 20 unique emoji per message (backend enforced)
  - [ ] Real-time update when others react

#### Feature 5: Push Notifications
- **User Story:** As a team member, I want notifications so that I don't miss important messages
- **Acceptance Criteria:**
  - [ ] Receive push for new messages (except muted channels)
  - [ ] Show sender name and message preview
  - [ ] Tapping notification opens specific channel
  - [ ] @mentions receive priority notification

#### Feature 6: Real-time Updates
- **User Story:** As a team member, I want instant message delivery so that conversations flow naturally
- **Acceptance Criteria:**
  - [ ] New messages appear instantly via Ably subscription
  - [ ] **Typing indicator:** Show "John is typing..." with animated dots at bottom of chat (show names, not just "someone")
  - [ ] Update reactions in real-time when others react
  - [ ] **Read receipts:** Show "Read by 5" below message, tappable to see who read
  - [ ] Handle connection loss gracefully with reconnection and visual indicator

### Should Have Features

#### Feature 7: Message Search
- **User Story:** As a user, I want to search messages so that I can find past conversations
- **Acceptance Criteria:**
  - [ ] **Search bar:** Icon in channel app bar, tap to reveal search input
  - [ ] Search within current channel only (global search out of scope)
  - [ ] Highlight matching text in results
  - [ ] Results show in context with messages above/below
  - [ ] Tap result to scroll to message in full conversation

#### Feature 8: Edit/Delete Messages
- **User Story:** As a user, I want to edit/delete my messages so that I can fix mistakes
- **Acceptance Criteria:**
  - [ ] **Access:** Long-press message to show action menu (Edit, Delete, Copy, Reply)
  - [ ] Edit own messages within 24 hours (backend enforced)
  - [ ] Delete own messages (soft delete, shows "[deleted]" in gray italic)
  - [ ] **Edited indicator:** Small "(edited)" text in gray after message content

#### Feature 9: Mentions Inbox
- **User Story:** As a user, I want a mentions inbox so that I can see all messages where I was tagged
- **Acceptance Criteria:**
  - [ ] **Location:** Separate tab alongside channels list (Channels | Mentions)
  - [ ] List all messages where user was @mentioned, sorted by recency
  - [ ] Show channel name, sender, message preview, and timestamp
  - [ ] Tap to navigate to original message in channel context
  - [ ] Badge on Mentions tab showing unread mention count

#### Feature 10: Channel Muting
- **User Story:** As a user, I want to mute channels so that I can reduce notification noise
- **Acceptance Criteria:**
  - [ ] **Access:** Long-press channel in list, or menu in channel app bar
  - [ ] Toggle mute per channel
  - [ ] Muted channels don't send push notifications (except @mentions still notify)
  - [ ] **Visual indicator:** Mute icon next to channel name in list

### Could Have Features

#### Feature 11: Image Attachments
- **User Story:** As a user, I want to share photos so that I can communicate visually
- **Acceptance Criteria:**
  - [ ] Attach images from camera or gallery via attachment button in input bar
  - [ ] Compress before upload (max 1MB, similar to avatar upload)
  - [ ] **Display:** Medium thumbnail within message bubble, tap for full-screen gallery view
  - [ ] Show upload progress indicator while sending
  - [ ] Rate limit: 10 uploads/minute (backend enforced)

#### Feature 12: Reply Threading
- **User Story:** As a user, I want to reply to specific messages so that context is preserved
- **Acceptance Criteria:**
  - [ ] **Access:** Swipe left on message, or long-press → Reply
  - [ ] **Quote display:** Compact preview bar above reply - thin colored left border, sender name, truncated text
  - [ ] Tap quoted preview to scroll to original message
  - [ ] Replies appear inline in conversation (not separate thread view)

#### Feature 13: Link Previews
- **User Story:** As a user, I want links to show previews so that I can see what's being shared
- **Acceptance Criteria:**
  - [ ] Detect URLs in messages automatically
  - [ ] **Display:** Preview card below message with thumbnail image, title, description
  - [ ] Tap preview to open link in browser
  - [ ] Graceful fallback if preview cannot be fetched (just show URL)

### Won't Have (This Phase)

- **Voice messages**: Audio recording/playback not in scope
- **Video calling**: No real-time video/audio calls
- **File attachments**: Only images, no documents/PDFs
- **Message translation**: No auto-translate
- **Channel creation by staff**: Only managers+ can create channels
- **Direct messages (DMs)**: Phase 1 is channel-based only
- **Message pinning**: No pinned messages feature
- **Polls/surveys**: No in-chat voting

## Detailed Feature Specifications

### Permissions Matrix

| Action | Staff | Manager | Owner/GM |
|--------|-------|---------|----------|
| View public channels | ✅ | ✅ | ✅ |
| View manager-only channels | ❌ | ✅ | ✅ |
| View owner-only channels | ❌ | ❌ | ✅ |
| Send messages | ✅ | ✅ | ✅ |
| Edit own messages (24h) | ✅ | ✅ | ✅ |
| Delete own messages | ✅ | ✅ | ✅ |
| Delete others' messages | ❌ | ❌ | ✅ |
| Add reactions | ✅ | ✅ | ✅ |
| @mention individuals | ✅ | ✅ | ✅ |
| @mention @staff/@managers | ✅ | ✅ | ✅ |
| Pin/unpin channels | ✅ | ✅ | ✅ |
| Mute channels | ✅ | ✅ | ✅ |
| Create channels | ❌ | ✅ | ✅ |
| Edit channel settings | ❌ | ✅ (own) | ✅ |
| Add members to channels | ❌ | ✅ | ✅ |
| Remove members from channels | ❌ | ✅ | ✅ |
| Archive/delete channels | ❌ | ❌ | ✅ |
| View read receipts | ✅ | ✅ | ✅ |

### Channel Provisioning & Lifecycle

**Channel Types:**
- **Default Store Channel**: Auto-created for each store, all employees have access, cannot be deleted
- **Public Channels**: Created by managers, visible to all employees in the store
- **Manager-only Channels**: Created by managers/owners, restricted to manager+ roles
- **Owner-only Channels**: Created by owners, restricted to owner/GM roles only

**Channel Creation:**
1. Manager/Owner opens channel list → taps "+" button
2. Enters channel name (1-100 characters, unique within store)
3. Selects access level: Public, Manager-only, or Owner-only
4. Optionally adds description (max 500 characters)
5. Channel is created and creator is auto-added

**Channel Membership:**
- **Auto membership:** Based on role + access level (e.g., all managers auto-join manager-only channels)
- **Manual membership:** Managers can manually add/remove individuals from channels they manage
- **Default channel:** Cannot remove self from default store channel

**Channel Archival (Owner-only):**
- Archived channels are hidden from list but messages are retained
- Archived channels can be unarchived by owners
- No permanent deletion in Phase 1 (compliance requirement)

**Scope Boundaries (Phase 1):**
- Single-store channels only (no cross-store messaging)
- BuyerKiosk Team app + BuyerKiosk Live app both ship with chat
- All active employees of a store can access chat

### Notification Behavior Specification

**Notification Priority Rules:**
| Trigger | Priority | Sound | Badge |
|---------|----------|-------|-------|
| @mention (individual) | High | Yes | +1 |
| @mention (@managers/@staff) | High | Yes | +1 |
| New message (unmuted channel) | Normal | Yes | +1 |
| New message (muted channel) | Silent | No | +1 (badge only) |
| Reaction on your message | Low | No | No |

**Batching/Grouping:**
- Multiple messages from same channel within 30 seconds are grouped into single notification
- Shows "3 new messages in #General" rather than 3 separate notifications

**Quiet Hours:** Not in Phase 1 scope (enhancement for future)

**Mention Overrides:**
- @mentions ALWAYS notify, even in muted channels
- @mentions ALWAYS show push notification (no grouping)

### Read Receipt Behavior

**Definition of "Read":**
- A message is marked as "read" when it is scrolled into the visible viewport AND remains visible for ≥500ms
- Read state is synced per-device but aggregated across all devices for display

**Privacy:**
- All users can see "Read by N" count
- Tapping "Read by N" shows list of names who read (no timestamps per reader)
- Users CANNOT disable read receipts in Phase 1 (may add preference later)
- Read receipts are visible to all channel members (no manager-only visibility)

**Multi-device:**
- Reading on one device marks as read on all devices
- Sync occurs within 2 seconds via Ably

### Feature: @Mentions System
**Description:** Users can @mention teammates to notify them directly. Mentions use `@firstname.lastname` syntax and trigger priority notifications.

**User Flow:**
1. User types "@" in message input
2. System shows autocomplete dropdown with channel members
3. User selects member (or continues typing to filter)
4. Mention appears highlighted in input
5. On send, mentioned user receives notification
6. Mention appears clickable/highlighted in message

**Business Rules:**
- Only channel members can be mentioned
- Mentioning someone who left the channel is invalid
- **Role mentions supported:** @managers, @staff (notify all users with that role in channel)
- @everyone/@here NOT supported (Phase 1)
- Mentions appear in user's mentions inbox

**Edge Cases:**
- User types "@" but doesn't complete → treat as literal "@"
- Mentioned user has muted channel → still receives mention notification
- User mentions themselves → no self-notification

## Comprehensive Edge Cases

### Message Delivery
| Scenario | Expected Behavior |
|----------|-------------------|
| Duplicate send (network retry) | Idempotency key prevents duplicate; same message shown once |
| Out-of-order delivery | Messages ordered by server timestamp, not arrival time |
| Send during connection loss | Show "sending" state, retry when reconnected, show error after 30s |
| Very long message (>4000 chars) | Truncate at 4000 chars, show character counter near limit |

### Pagination & Caching
| Scenario | Expected Behavior |
|----------|-------------------|
| Gap in pagination (deleted messages) | Show smooth scroll, no visible gap |
| Cache invalidation | Cache last 100 messages per channel; refresh on open |
| Offline cache limit | Store last 50 messages per channel for offline viewing |

### Edit/Delete Timing
| Scenario | Expected Behavior |
|----------|-------------------|
| Edit while another user viewing | Update in real-time for viewer |
| Delete while another user viewing | Replace with "[deleted]" in real-time |
| Edit after 24h window | Show error "Edit window expired", offer to send new message |
| Edit race condition (two devices) | Last-write-wins based on server timestamp |

### Permission Changes
| Scenario | Expected Behavior |
|----------|-------------------|
| Role demoted mid-session | On next channel list refresh, restricted channels disappear |
| Role promoted mid-session | New channels appear on next list refresh |
| Removed from channel while viewing | Show "You no longer have access" and redirect to channel list |
| Employee terminated | Immediate removal from all channels, messages retained |

### Multi-device
| Scenario | Expected Behavior |
|----------|-------------------|
| Read on device A, open on device B | Device B shows messages as read |
| Composing on two devices | No conflict; both can send (separate messages) |
| Logout on one device | Other devices remain logged in |

### Real-time Connection
| Scenario | Expected Behavior |
|----------|-------------------|
| Ably disconnect | Show "Reconnecting..." banner; retry with exponential backoff |
| Ably reconnect after >5min | Fetch missed messages from API before resuming real-time |
| Ably service down | Fallback to polling every 30s; show "Limited connectivity" |
| Push received while logged out | Store notification, show on next app open |

### Timestamps & Timezones
| Scenario | Expected Behavior |
|----------|-------------------|
| User in different timezone | Timestamps show in user's local timezone |
| DST change while viewing | Timestamps auto-adjust on next section header |
| Messages around midnight | Group correctly by local date |

### Rate Limits
| Scenario | Expected Behavior |
|----------|-------------------|
| Hit message rate limit | Show "Slow down! You can send another message in X seconds" |
| Hit reaction rate limit | Disable reaction button briefly, show countdown |
| Hit upload rate limit | Show "Please wait before uploading another image" |

**UI Specifications:**
- **Autocomplete:** Floating dropdown above keyboard, showing avatar + "Firstname Lastname" for each match
- **Mention highlight:** Brand purple background tint on @name in message text
- **Mention tap action:** Opens mini profile card popup (name, role, avatar, "Message" action button)

## Success Metrics

### Key Performance Indicators

| Metric | Target | Definition | Measurement |
|--------|--------|------------|-------------|
| **Adoption** | 60% within 7 days | % of active users (logged in ≥1x/week) who send ≥1 message | Analytics: `message_sent` events / active users |
| **Engagement** | 5+ msgs/user/day | Average messages sent per active user per day | Analytics: daily `message_sent` / DAU |
| **Quality** | <1% failure rate | % of send attempts that fail after all retries | Analytics: `message_failed` / `message_sent` |
| **Delivery Latency** | p95 < 500ms | Time from send tap to message visible to recipients | Analytics: `message_received.latency_ms` |
| **Business Impact** | 20% reduction | Self-reported decrease in third-party app usage | Post-launch survey (30-day) |

**Baseline Measurement:** Pre-launch survey of 50 users on current messaging app usage patterns

### Operational Metrics

| Metric | Target | Purpose |
|--------|--------|---------|
| Ably reconnect rate | <5% of sessions | Monitor real-time stability |
| Push notification open rate | >30% | Measure notification relevance |
| Mention-to-response time | <10 min median | Measure urgency handling |
| Channel mute rate | <20% of users | Ensure notification quality |

### Tracking Requirements

| Event | Properties | Purpose |
|-------|------------|---------|
| `channel_opened` | channel_id, source (list/notification/deeplink) | Track entry points |
| `message_sent` | channel_id, has_mentions, has_attachment | Measure engagement |
| `message_received` | channel_id, is_mention, latency_ms | Measure real-time performance |
| `reaction_added` | message_id, emoji | Track reaction usage |
| `mention_tapped` | source (inbox/inline) | Measure mentions feature usage |
| `role_mention_sent` | role (managers/staff), channel_id | Track role mention usage |
| `channel_muted` | channel_id | Track muting behavior |
| `channel_pinned` | channel_id, pinned (true/false) | Track pinning behavior |
| `search_performed` | query_length, result_count | Measure search utility |

---

## Constraints and Assumptions

### Constraints
- **API Specification:** `docs/api/staff-chat-mobile-openapi.yaml` (19 endpoints, source of truth)
- **UI Approach:** Custom Flutter UI (not chatview package) for full control and consistency
- **Shared Code:** Must create `buyerkiosk_chat` shared package for both Team and Live apps
- **Theming:** Dark mode required at launch (follow system preference)
- **Rate Limits:** 30 msgs/min, 20 reactions/min, 10 uploads/min (enforced by backend)
- **Edit Window:** 24-hour limit on message editing
- **Message Retention:** Messages retained indefinitely for compliance (no auto-delete in Phase 1)

### Dependencies

| Dependency | Owner | Status | Notes |
|------------|-------|--------|-------|
| OpenAPI Spec | Backend | ✅ Ready | `docs/api/staff-chat-mobile-openapi.yaml` |
| Ably Real-time | Platform | ✅ Ready | Already integrated for push in Live app |
| FCM/APNs Push | Platform | ✅ Ready | Already integrated for notifications |
| User/Role API | Backend | ✅ Ready | `/api/mobile/me` returns roles and store assignments |
| Image Upload Storage | Backend | 🔄 TBD | S3/CDN for attachments (Could Have feature) |
| Analytics Pipeline | Platform | 🔄 TBD | Events → Mixpanel/Amplitude (team to confirm) |

### Assumptions
- Users have reliable internet (WiFi or cellular) during chat use
- Ably service maintains 99.9% uptime for real-time delivery
- Backend API matches OpenAPI spec exactly (contract-first development)
- Users are familiar with basic chat app patterns (WhatsApp, iMessage)
- Role/store membership changes propagate within 5 minutes to chat permissions
- FCM/APNs deep links are functional for notification tap handling

## Risks and Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Ably connection instability | High | Low | Implement reconnection logic with exponential backoff |
| Message delivery failures | High | Low | Queue messages locally, retry with idempotency key |
| Overwhelming notifications | Medium | Medium | Smart notification grouping, easy mute access |
| UI inconsistency between apps | Medium | Medium | Shared Flutter package with strict theming |

## UI Design Specifications

### Visual Style Summary

| Element | Specification |
|---------|---------------|
| **Message Bubbles** | WhatsApp-style: own messages right-aligned (brand purple #7c3aed), others left-aligned (gray/white) |
| **Avatars** | Show only for first message in consecutive group from same sender |
| **Timestamps** | Grouped as section headers (e.g., "Today 2:30 PM"), not per-message |
| **System Messages** | Centered gray italic text, no bubble |
| **Bubble Color (Own)** | Brand purple #7c3aed |
| **Bubble Color (Others)** | Light gray (light mode), darker gray (dark mode) |
| **Dark Mode** | Required, follows system preference |

### Interaction Patterns

| Interaction | Action |
|-------------|--------|
| **Swipe Right** | Open reaction picker |
| **Swipe Left** | Reply to message |
| **Long Press** | Action menu (Edit, Delete, Copy, Reply) |
| **Tap Avatar/Name** | Mini profile card popup |
| **Tap Mention** | Mini profile card popup |
| **Tap Reaction** | Show who reacted |
| **Tap "Read by N"** | Show list of readers |

### Component Specifications

| Component | Details |
|-----------|---------|
| **Input Bar** | Attachment button \| Text field \| Emoji button \| Send arrow |
| **Reaction Picker** | Quick bar (6 common emojis) + "more" for full keyboard |
| **Reactions Display** | Chips below bubble (emoji + count) |
| **Mention Autocomplete** | Dropdown above keyboard with avatar + name |
| **Mention in Message** | Purple background tint on @name |
| **Reply Quote** | Compact preview bar with colored left border, sender, truncated text |
| **Link Preview** | Card below message (thumbnail, title, description) |
| **Image Attachment** | Medium thumbnail in bubble, tap for full-screen |
| **Edited Indicator** | Small "(edited)" gray text after content |
| **Typing Indicator** | "John is typing..." with animated dots at bottom |
| **Read Receipts** | "Read by 5" below message, tappable |

### States

| State | Display |
|-------|---------|
| **Loading** | Skeleton loaders mimicking message layout |
| **Empty Channel** | Illustration + "Start the conversation!" prompt |
| **Error** | Inline error banner with retry button |
| **Offline** | Read-only mode, cannot compose |
| **Unread (scrolled up)** | Floating "Jump to new" button |
| **Muted Channel** | Mute icon in channel list |

### Navigation Structure

```
Chat Tab
├── Channels Tab (default)
│   ├── Pinned Channels Section
│   └── Recent Channels Section (sorted by activity)
└── Mentions Tab
    └── List of @mentions (sorted by recency)

Channel Screen
├── App Bar (channel name, search icon, menu)
├── Message List (infinite scroll)
├── Typing Indicator
└── Input Bar
```

## Open Questions

### UI/UX Decisions - RESOLVED
All critical UI decisions have been made:
- [x] Message bubble design: WhatsApp-style (own right/purple, others left/gray)
- [x] Timestamp display: Grouped by time as section headers
- [x] Avatar display: First in consecutive group only
- [x] Dark mode support: Required (follow system preference)
- [x] Swipe gestures: Right = react, Left = reply
- [x] Empty channel state: Illustration + "Start the conversation!" prompt
- [x] Loading states: Skeleton loaders
- [x] Error states: Inline with retry button
- [x] Typing indicator: Show names ("John is typing...")
- [x] Read receipts: "Read by N" count, tap to see who
- [x] Offline mode: Read-only (no offline compose)

### Remaining Questions - RESOLVED
- [x] Role mentions: Yes, support @managers and @staff (notify all with that role)
- [x] Channel pinning: Manual pin only (long-press to pin/unpin)
- [ ] Empty state illustration: Use existing brand illustration or create new? (Design decision)

---

## Supporting Research

### Competitive Analysis

| Feature | WhatsApp | Slack | Discord | Our Target |
|---------|----------|-------|---------|------------|
| Channels | No (groups) | Yes | Yes | Yes |
| Reactions | Limited | Yes | Yes | Yes |
| Threads | No | Yes | No | Could Have |
| Typing | Yes | Yes | Yes | Yes |
| Read receipts | Yes | No | No | Yes |
| Mentions | Yes | Yes | Yes | Yes |
| Search | Yes | Yes | Yes | Should Have |
| Offline compose | Yes | No | No | Read-only |

### User Research
Based on existing BuyerKiosk user base:
- Teams currently use WhatsApp groups for informal coordination
- Managers struggle to reach all staff through official channels
- No visibility into whether shift-related messages were read
- Context switching between scheduling app and messaging app is friction

### Market Data
- Slack reports 32.5% of messages include emoji reactions
- WhatsApp has 2B+ users familiar with chat patterns
- 65% of frontline workers prefer mobile-first communication tools
- Microsoft Teams workplace chat adoption grew 894% during 2020-2023
