diff --git a/UX.md b/UX.md index 25dbf8c..0a67250 100644 --- a/UX.md +++ b/UX.md @@ -2,26 +2,28 @@ ## 1. Purpose -This document defines the target frontend UX for RpgRoller based on `REQUIREMENTS.md`. +This document defines the target frontend UX for RpgRoller based on `REQUIREMENTS.md` and the latest review edits. It is the design baseline we will iterate on before implementing new frontend code. Primary goals: -- Make campaign play flow fast: select context, roll, see results. +- Make campaign play flow fast: select character, roll, see results. - Keep role rules clear: player, GM, and visibility boundaries. - Preserve trust: deterministic behavior, clear validation, append-only log feel. -- Keep the interface simple enough for live-session use on desktop and mobile. +- Keep the interface simple for live-session use on desktop, tablet, and mobile. ## 2. Scope In scope for this UX: - Authentication (register/login/logout) -- Campaign creation and selection +- Two authenticated screens: + - `Play` screen for character sheet and log + - `Campaign Management` screen for campaign details and management actions - Character create/edit/activate - Skill create/edit - Skill rolling with public/private visibility -- Campaign detail view and campaign log with live updates +- Campaign log with live updates Out of scope for v1 UX: @@ -29,6 +31,7 @@ Out of scope for v1 UX: - Advanced profile settings - Campaign invitations or approvals - Log filtering/search/export +- First-time onboarding tours ## 3. Personas and Permissions @@ -36,14 +39,14 @@ Out of scope for v1 UX: - Can create and edit own characters. - Can create and edit skills on own characters. -- Can roll own/authorized character skills. +- Can roll own or authorized character skills. - Can see campaign log entries allowed by visibility rules. ### GM -- All player capabilities for owned/authorized characters. +- All player capabilities for owned or authorized characters. - Can create campaigns and choose rulesets. -- Can edit characters/skills in campaigns they GM. +- Can edit characters and skills in campaigns they GM. - Can view all rolls in their campaigns, including private rolls. ### Future Observer (non-v1) @@ -54,97 +57,125 @@ Out of scope for v1 UX: 1. Context first: always show current campaign and active character status at top. 2. One action, one confirmation: each mutation gives immediate success/failure feedback. -3. Permission-aware UI: hide/disable actions the user cannot perform. +3. Permission-aware UI: hide or disable actions the user cannot perform. 4. Real-time clarity: live updates should feel stable, not jittery. -5. Progressive disclosure: advanced editing appears only when needed. +5. Progressive disclosure: deep management stays outside the play screen. -## 5. Information Architecture +## 5. Product Decisions from Review -Single-page app with two top-level states: +The following decisions are now locked for v1: -- Unauthenticated state -- Authenticated workspace +1. Campaign switching persistence: per tab/session, not global account-level persistence. +2. Edit UX: every edit uses an explicit edit button that opens a popup modal with a dedicated form and submit action. +3. Private roll presentation: visually differentiate private entries depending on viewer perspective (GM vs roller). +4. Log filtering: deferred, no filtering controls in v1. +5. Onboarding: no onboarding hints in v1. -Authenticated workspace is organized into five persistent regions: +## 6. Information Architecture -1. Header status bar -2. Campaign context rail -3. Character panel -4. Skill + roll panel -5. Campaign details + log panel +The app has two top-level states: -## 6. Global Layout +- Unauthenticated +- Authenticated -### Desktop (>= 1024px) +Authenticated state has two screens: -- Top sticky header with app identity, user chip, API/connection status, logout. -- Three-column body: - - Left: campaign context + quick actions - - Middle: characters + skills + roll controls - - Right: campaign details + live log +1. `Play` (default after login) +2. `Campaign Management` -### Tablet (700px-1023px) +Global authenticated navigation: -- Two columns with log panel below details. -- Roll controls remain visible without excessive scrolling. +- Header includes app identity, current user chip, campaign context, connection status, and screen switch control. +- Screen switch is always available: `Play` <-> `Campaign Management`. -### Mobile (< 700px) +## 7. Global Layout -- Single column, section cards in this order: - 1. status/context - 2. campaigns - 3. characters - 4. skills/roll - 5. details - 6. log -- Sticky bottom "Roll" action when a skill is selected. +### 7.1 Play Screen - Desktop (>= 1024px) -## 7. Key User Flows +- Top sticky header. +- Main body is exactly two columns: + - Left column (2/3 width): character-focused area. + - Right column (1/3 width): live campaign log. -### 7.1 First-time GM flow +Left column contains: + +- Character picker (icon tab strip) +- One character sheet (selected character only) +- Skills list for selected character +- Roll controls +- Last roll summary + +Right column contains: + +- Campaign log feed only + +Campaign details and management controls are excluded from this screen. + +### 7.2 Play Screen - Tablet and Mobile (< 1024px) + +- Single active panel area. +- Bottom navigation bar toggles between two views: + - `Character` + - `Log` +- Character and log are not shown side-by-side on tablet/mobile. +- Header remains visible with context and connection status. + +### 7.3 Campaign Management Screen (all breakpoints) + +- Focused on campaign setup and administration. +- Contains campaign details, campaign creation, campaign selection, and management operations. +- Character sheet and rolling controls are not primary in this screen. + +## 8. Key User Flows + +### 8.1 First-time GM flow 1. Register 2. Login -3. Create campaign with ruleset -4. Create character in campaign -5. Activate character -6. Create skill -7. Roll skill (public/private) -8. Confirm result appears in campaign log +3. Open `Campaign Management` +4. Create campaign with ruleset +5. Create or move character into campaign +6. Activate character +7. Switch to `Play` +8. Create skill +9. Roll skill (public/private) +10. Confirm result appears in log -### 7.2 Player joins campaign flow +### 8.2 Player participation flow 1. Register/login -2. Select existing campaign from accessible campaigns -3. Create character in that campaign -4. Activate character -5. Add/edit skills -6. Roll and view log with visibility rules +2. Open `Campaign Management` +3. Select accessible campaign +4. Create character in that campaign +5. Activate character +6. Switch to `Play` +7. Add or edit skills +8. Roll and view log with visibility rules -### 7.3 GM oversight flow +### 8.3 GM oversight flow -1. Open campaign -2. Inspect all visible characters and skills -3. Observe all roll events, including private -4. Validate campaign progression via append-only log +1. Open `Play` +2. Switch between characters with icon tabs +3. Observe roll events in live log +4. Move to `Campaign Management` when campaign setup or details edits are needed -## 8. Screen-by-Screen Specification +## 9. Screen Specifications -## 8.1 App Load and Session Restore +## 9.1 App Load and Session Restore States: - Initial: "Connecting..." - Healthy + anonymous: show auth view -- Healthy + logged in: show workspace +- Healthy + logged in: show `Play` screen - API unhealthy: show non-blocking banner with retry CTA Behavior: - Call health endpoint first, then rulesets and session context. -- If session invalid/expired, clear local authenticated state and show auth view. +- If session invalid or expired, clear local authenticated state and show auth view. -## 8.2 Authentication View +## 9.2 Authentication View Elements: @@ -167,16 +198,16 @@ Validation: Feedback: - Inline field errors pre-submit -- Top-level form error for server rejects (e.g., duplicate username, invalid credentials) +- Top-level form error for server rejects (duplicate username, invalid credentials) - Success message after register -## 8.3 Workspace Header +## 9.3 Shared Header (Authenticated) Shows: - Logged-in display name + username -- Active character summary (name or "None selected") -- Current campaign summary (name or "No campaign context") +- Current campaign name (or "No campaign selected") +- Active character summary (or "None selected") - Live state indicator: - Connected - Reconnecting @@ -184,85 +215,53 @@ Shows: Actions: +- Switch screen (`Play` / `Campaign Management`) +- Manual refresh - Logout -- Manual refresh (soft reload campaign state and log) -## 8.4 Campaign Panel +## 9.4 Play Screen - Character Column (2/3) -Elements: +### Character Picker -- Create campaign form: - - Campaign name - - Ruleset select (`d6`, `dnd5e`) - - Create button -- Campaign switcher: - - Accessible campaigns list - - Current selection badge +- Horizontal icon tab control. +- One icon per available character in the current campaign scope. +- Active character has persistent visual highlight. +- Selecting a tab changes the character sheet context. -Behavior: +### Character Sheet -- Creating campaign auto-selects it. -- Switching campaign updates character/skill/log panels. -- If no campaigns exist, show empty state with "Create your first campaign". +Shows selected character details: -## 8.5 Character Panel +- Character name +- Owner +- Campaign affiliation +- Active badge if it matches session active character -Elements: +Actions: -- Character create/edit form: - - Name - - Campaign target selector (for move/edit flow) - - Save button -- Character list for selected campaign -- Activate character button +- `Edit Character` button -> opens modal form +- `Activate Character` button (enabled only when permitted) -Behavior: +### Skills and Roll Commands -- Distinguish: - - Active character (highlight + "Active" pill) - - Selected character (for editing/skill operations) -- GM sees all campaign characters. -- Non-GM sees own characters in selected campaign. +Shows selected character skills list and selected skill details. -## 8.6 Skill and Rolling Panel +Actions: -Elements: +- `Create Skill` button -> modal form +- `Edit Skill` button -> modal form +- Roll command panel: + - Visibility selector (`public`, `private`) + - `Roll Skill` primary action -- Skill create/edit form: - - Skill name - - Dice expression - - Create / Update actions -- Skill picker scoped to selected character -- Roll form: - - Visibility toggle (`public`, `private`) - - Roll button -- Last roll preview card: - - Result total - - Breakdown - - Visibility - - Timestamp +Last roll card: -Behavior: +- Result total +- Breakdown +- Visibility +- Timestamp -- Skill actions disabled until a character is selected. -- Roll action disabled until a skill is selected. -- On roll success: - - update preview instantly - - refresh log (or patch in optimistic entry then confirm) - -## 8.7 Campaign Details Panel - -Shows: - -- Campaign metadata: name, ruleset, GM -- Characters visible to current user -- Skills visible to current user - -Goals: - -- Provide a trusted "current truth" snapshot for context before rolling. - -## 8.8 Campaign Log Panel +## 9.5 Play Screen - Log Column (1/3) Shows chronological roll entries with: @@ -272,19 +271,51 @@ Shows chronological roll entries with: - Visibility badge - Timestamp -Visibility handling: +Visibility rules: - Public rolls visible to all participants. - Private rolls visible only to roller and GM. -- No placeholders for hidden private rolls (avoid leaking that a hidden event exists). +- No placeholders for hidden private rolls. -Live behavior: +Perspective styling for private rolls: -- SSE-driven refresh when campaign version changes. -- Heartbeat-aware connection status. -- Recover from disconnect with automatic retry and full log refresh. +- Roller view: private badge style A (for "you rolled private") +- GM view: private badge style B (for "GM-visible private") -## 9. Validation and Error UX +## 9.6 Campaign Management Screen + +This screen contains all campaign details and management options. + +Sections: + +1. Campaign selector and campaign summary +2. Create campaign form (name + ruleset) +3. Campaign details card (name, ruleset, GM) +4. Character management list and actions + +Edit pattern: + +- All edits use explicit edit buttons. +- Edit buttons open popup modals with dedicated forms. +- No inline row editing. + +## 9.7 Tablet/Mobile Bottom Bar Behavior + +Applies to both tablet and mobile in `Play` screen. + +Bottom bar items: + +- `Character` +- `Log` + +Rules: + +- Exactly one panel active at a time. +- Active tab state is preserved while user remains on current page session. +- Roll action remains accessible in `Character` panel. +- Connection status remains visible in header regardless of active panel. + +## 10. Validation and Error UX Pre-submit client validation: @@ -299,14 +330,14 @@ Server error mapping: | `invalid_username`, `invalid_display_name`, `invalid_password` | Show field-level + summary errors in auth forms | | `duplicate_username` | Register username field error with suggestion to choose another | | `invalid_credentials` | Login summary error only (no account existence hints) | -| `invalid_campaign_name`, `invalid_character_name`, `invalid_skill_name` | Field-level inline error | +| `invalid_campaign_name`, `invalid_character_name`, `invalid_skill_name` | Field-level inline error in modal form | | `invalid_ruleset`, expression validation failures, `invalid_visibility` | Field-level error and helper text with valid examples | | `campaign_not_found`, `character_not_found`, `skill_not_found` | Non-blocking panel alert + auto-refresh relevant list | | `forbidden` | Explain permission rule and remove unavailable actions | | `unauthorized` | Clear session and return to auth view with message | -| `no_active_character` | Show empty-state CTA: "Activate a character to continue" | +| `no_active_character` | Show CTA to activate a character | -## 10. Empty, Loading, and Disabled States +## 11. Empty, Loading, and Disabled States Required empty states: @@ -322,21 +353,21 @@ Loading patterns: - Disabled form actions with spinner when mutation is in flight - Maintain prior data view during refresh to reduce layout jumps -## 11. Real-Time and Sync Rules +## 12. Real-Time and Sync Rules -- Campaign details and log are campaign-scoped. +- `Play` screen log is campaign-scoped. - Subscribe to SSE only when: - user is authenticated - - a campaign is selected -- On event: - - fetch campaign details - - fetch campaign log + - campaign is selected +- On state event: + - refresh current character context data + - refresh campaign log - On SSE failure: - exponential backoff reconnect - - status indicator changes to "Reconnecting" - - keep manual refresh available + - status indicator switches to "Reconnecting" + - manual refresh remains available -## 12. Accessibility Requirements +## 13. Accessibility Requirements - Full keyboard operation for all controls. - Visible focus ring and logical tab order. @@ -346,44 +377,46 @@ Loading patterns: - global success/error toasts - roll result updates - reconnect state changes +- Icon-tab character picker must include readable text labels for assistive tech. -## 13. Content and Copy Guidance +## 14. Content and Copy Guidance -- Use plain language and short action labels: - - "Create Campaign", "Activate Character", "Roll Skill" -- Avoid technical jargon unless part of ruleset terms. -- Error tone: corrective and direct, no blame. -- Date/time format: local time display with ISO tooltip. +- Use plain language and short action labels. +- Keep critical actions explicit: + - "Create Campaign" + - "Activate Character" + - "Roll Skill" +- Error tone: corrective and direct. +- Date/time: local display with ISO tooltip. -## 14. Visual Direction (for implementation phase) +## 15. Visual Direction (for implementation phase) -- Theme: tabletop utility UI with clear hierarchy, not generic admin dashboard. +- Theme: tabletop utility UI with clear hierarchy, not a generic admin dashboard. - Emphasize readability for dense gameplay sessions. +- Character picker should use icon tabs with strong selected-state affordance. - Use color semantics: - success for roll completion - warning for validation needs - - neutral badges for visibility and role labels -- Keep animation purposeful: - - subtle updates for log inserts - - connection-status transitions + - neutral role/visibility badges +- Keep motion purposeful: + - subtle log insert transitions + - connection state transitions -## 15. Requirements Traceability +## 16. Requirements Traceability | Requirement area | UX coverage | |---|---| | User management | Auth view with register/login/logout, secure failure messaging | -| Campaign management | Campaign create/select panel, ruleset assignment UI | -| Character management | Character create/edit/activate flows, ownership-aware rendering | +| Campaign management | Dedicated `Campaign Management` screen with ruleset assignment and details | +| Character management | Character picker + modal edit/create/activate flows | | Active character context | Persistent header context and activation CTA | -| Skill management | Skill form + ruleset-aware validation feedback | -| Dice rolling | Visibility toggle + deterministic result display | -| Campaign log | Chronological live log with permission filtering | +| Skill management | Skill create/edit modals + ruleset-aware validation feedback | +| Dice rolling | Visibility toggle + deterministic result display in `Play` screen | +| Campaign log | Dedicated log column (desktop) and log tab (tablet/mobile) with permission filtering | | Edge constraints | Disabled/forbidden/unauthorized handling and recovery UX | -## 16. Open Questions for Iteration +## 17. Next Iteration Targets -1. Should campaign switching be global and persistent across sessions, or per-tab only? -2. Do we want inline editing in lists, or keep all edits in dedicated forms? -3. Should private rolls be visually marked differently for GM vs roller perspective? -4. Is manual log filtering needed for v1 (character/skill/roller), or deferred? -5. Should we add lightweight onboarding hints for first-time users? +1. Define low-fidelity wireframes for `Play` and `Campaign Management`. +2. Define exact component contracts (props/state/events) for the frontend module split. +3. Define visual tokens (spacing, type scale, color roles) for implementation.