# UX Design Specification - Frontend ## 1. Purpose This document defines the target frontend UX for RpgRoller based on `REQUIREMENTS.md`. 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. - 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. ## 2. Scope In scope for this UX: - Authentication (register/login/logout) - Campaign creation and selection - Character create/edit/activate - Skill create/edit - Skill rolling with public/private visibility - Campaign detail view and campaign log with live updates Out of scope for v1 UX: - Observer role management UI (future role) - Advanced profile settings - Campaign invitations or approvals - Log filtering/search/export ## 3. Personas and Permissions ### Player - Can create and edit own characters. - Can create and edit skills on own characters. - Can roll own/authorized character skills. - Can see campaign log entries allowed by visibility rules. ### GM - All player capabilities for owned/authorized characters. - Can create campaigns and choose rulesets. - Can edit characters/skills in campaigns they GM. - Can view all rolls in their campaigns, including private rolls. ### Future Observer (non-v1) - Read-only campaign visibility, no mutation actions. ## 4. UX Principles 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. 4. Real-time clarity: live updates should feel stable, not jittery. 5. Progressive disclosure: advanced editing appears only when needed. ## 5. Information Architecture Single-page app with two top-level states: - Unauthenticated state - Authenticated workspace Authenticated workspace is organized into five persistent regions: 1. Header status bar 2. Campaign context rail 3. Character panel 4. Skill + roll panel 5. Campaign details + log panel ## 6. Global Layout ### Desktop (>= 1024px) - 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 ### Tablet (700px-1023px) - Two columns with log panel below details. - Roll controls remain visible without excessive scrolling. ### Mobile (< 700px) - 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. Key User Flows ### 7.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 ### 7.2 Player joins campaign 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 ### 7.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 ## 8. Screen-by-Screen Specification ## 8.1 App Load and Session Restore States: - Initial: "Connecting..." - Healthy + anonymous: show auth view - Healthy + logged in: show workspace - 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. ## 8.2 Authentication View Elements: - Register card: - Username - Display name - Password - Submit - Login card: - Username - Password - Submit Validation: - Username required - Display name required (register only) - Password required, min length 8 for register Feedback: - Inline field errors pre-submit - Top-level form error for server rejects (e.g., duplicate username, invalid credentials) - Success message after register ## 8.3 Workspace Header Shows: - Logged-in display name + username - Active character summary (name or "None selected") - Current campaign summary (name or "No campaign context") - Live state indicator: - Connected - Reconnecting - Offline fallback Actions: - Logout - Manual refresh (soft reload campaign state and log) ## 8.4 Campaign Panel Elements: - Create campaign form: - Campaign name - Ruleset select (`d6`, `dnd5e`) - Create button - Campaign switcher: - Accessible campaigns list - Current selection badge Behavior: - Creating campaign auto-selects it. - Switching campaign updates character/skill/log panels. - If no campaigns exist, show empty state with "Create your first campaign". ## 8.5 Character Panel Elements: - Character create/edit form: - Name - Campaign target selector (for move/edit flow) - Save button - Character list for selected campaign - Activate character button Behavior: - 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. ## 8.6 Skill and Rolling Panel Elements: - 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 Behavior: - 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 Shows chronological roll entries with: - Roller identity - Character + skill - Result and breakdown - Visibility badge - Timestamp Visibility handling: - 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). Live behavior: - SSE-driven refresh when campaign version changes. - Heartbeat-aware connection status. - Recover from disconnect with automatic retry and full log refresh. ## 9. Validation and Error UX Pre-submit client validation: - Required field checks for all forms - Password minimum length on register - Local non-empty checks for names and expressions Server error mapping: | Backend condition | UX behavior | |---|---| | `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_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" | ## 10. Empty, Loading, and Disabled States Required empty states: - No campaigns yet - No characters in selected campaign - No skills for selected character - No log entries yet - No active character Loading patterns: - Skeleton rows for lists - 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 - Campaign details and log are campaign-scoped. - Subscribe to SSE only when: - user is authenticated - a campaign is selected - On event: - fetch campaign details - fetch campaign log - On SSE failure: - exponential backoff reconnect - status indicator changes to "Reconnecting" - keep manual refresh available ## 12. Accessibility Requirements - Full keyboard operation for all controls. - Visible focus ring and logical tab order. - Labels for every input (placeholder is not label). - Contrast target >= WCAG AA. - Screen reader announcements for: - global success/error toasts - roll result updates - reconnect state changes ## 13. 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. ## 14. Visual Direction (for implementation phase) - Theme: tabletop utility UI with clear hierarchy, not generic admin dashboard. - Emphasize readability for dense gameplay sessions. - 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 ## 15. 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 | | 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 | | Edge constraints | Disabled/forbidden/unauthorized handling and recovery UX | ## 16. Open Questions for Iteration 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?