Skip to content

Latest commit

 

History

History
1097 lines (862 loc) · 32.2 KB

File metadata and controls

1097 lines (862 loc) · 32.2 KB

UI Improvements for D&D Session Processor

Date: 2025-11-16 Analysis Scope: Complete UI codebase including all tabs, components, and theme files Total Improvements Identified: 20


Table of Contents


🎯 Accessibility & Usability (Critical)

1. Missing ARIA Labels and Accessibility Attributes

Location: All interactive components across all tabs File References:

  • src/ui/process_session_tab_modern.py
  • src/ui/campaign_tab_modern.py
  • src/ui/characters_tab_modern.py
  • src/ui/settings_tools_tab_modern.py

Issue: Buttons, dropdowns, and file inputs lack proper ARIA labels for screen readers

Current State:

gr.Button("Start Processing", variant="primary")

Improvement Needed:

  • Add aria-label attributes to all interactive elements
  • Add role attributes for custom components
  • Include aria-describedby for form inputs with help text
  • Add aria-live regions for status updates and progress messages

Example Fix:

gr.Button(
    "Start Processing",
    variant="primary",
    elem_id="process-btn",
    elem_classes=["process-action"],
    # Add ARIA attributes via custom JS or Gradio's accessibility props
)

Impact: Makes the application unusable for visually impaired users Priority: 🔴 HIGH Effort: Medium (2-3 days)


2. No Keyboard Navigation Support

Location: Workflow stepper, accordions, tab navigation File References:

  • src/ui/process_session_components.py:68-94 (workflow stepper)
  • All accordion implementations

Issue: Users cannot navigate the UI efficiently with keyboard alone

Current State: No keyboard shortcuts, tab order not optimized

Improvement Needed:

  • Add keyboard shortcuts:
    • Ctrl+P or Cmd+P for "Start Processing"
    • Ctrl+S or Cmd+S for "Save Settings"
    • Ctrl+/ or Cmd+/ for help/shortcuts panel
    • Escape to close accordions/modals
  • Implement proper tab indexing with tabindex
  • Add skip-to-content links
  • Enable Enter key to trigger primary actions in forms
  • Add visual keyboard shortcut hints (e.g., button labels: "Process Ctrl+P")

Impact: Poor experience for keyboard-only users and power users Priority: 🔴 HIGH Effort: High (4-5 days)


3. Missing Focus Indicators ✅ COMPLETE

Status:Draft PR #141 (2025-11-25) - Ready for Merge Branch: feat-UI-3-focus-indicators Files Modified: src/ui/theme.py (+30, -8 lines) Location: src/ui/theme.py:119-137 (input focus styles)

Completed State:

  • ✅ 3px focus ring for ALL interactive elements (buttons, links, inputs, accordions)
  • ✅ Uses :focus-visible pseudo-class (best practice - only shows on keyboard nav)
  • ✅ Theme-aware using CSS variables (var(--primary-200))
  • ✅ Dark mode compatible
  • ✅ Removed redundant old focus styles for text inputs
  • ✅ Accessibility improvement for keyboard navigation and screen readers

Original Issue: Focus states exist but are inconsistent; some elements have no visible focus

Current Problem:

input[type="text"]:focus {
    border-color: #6366f1 !important;
    box-shadow: 0 0 0 3px rgb(99 102 241 / 0.1) !important;
}

But buttons, accordions, and custom components lack focus styles

Improvement Needed:

  • Add consistent 3px focus ring to ALL interactive elements
  • Ensure focus is not trapped in accordions
  • Implement focus management when modals/sections open
  • Add focus styles for:
    • Buttons (currently missing)
    • Accordion headers
    • Dropdown arrows
    • Table rows (when interactive)
    • File upload zones

Example CSS Addition:

button:focus,
.btn-primary:focus,
.btn-secondary:focus {
    outline: 3px solid #6366f1 !important;
    outline-offset: 2px !important;
}

details summary:focus {
    outline: 3px solid #6366f1 !important;
    outline-offset: 2px !important;
}

Impact: Users can't tell which element is active during keyboard navigation Priority: 🟡 MEDIUM Effort: Low (1 day)


⚡ Loading States & Feedback

4. Buttons Don't Show Loading States

Location: src/ui/process_session_components.py:324-336 and all action buttons File Reference: src/ui/helpers.py:184-210 (UIComponents.create_action_button)

Issue: When users click "Start Processing" or "Run Preflight Checks", the button doesn't show it's working

Current State:

components["process_btn"] = UIComponents.create_action_button(
    "Start Processing", variant="primary", size="lg", full_width=True
)

Improvement Needed:

  • Show spinner icon while processing: ⏳ Processing...
  • Disable button during operation to prevent double-clicks
  • Change color to indicate active state
  • Restore original state when complete

Example Implementation:

def start_processing():
    # Update button to loading state
    yield gr.update(value="⏳ Processing...", interactive=False, variant="secondary")

    # Do processing work
    result = process_session(...)

    # Restore button
    yield gr.update(value="Start Processing", interactive=True, variant="primary")
    return result

Impact: Users click multiple times, unsure if action registered; can trigger duplicate processing Priority: 🔴 HIGH Effort: Low (1 day across all buttons)


5. No Progress Percentage Display

Location: src/ui/process_session_components.py:338-342 (overall_progress_display)

Issue: Progress bars show qualitative status but no quantitative metrics

Current State: Shows "Processing..." without percentage or estimated time

Improvement Needed:

# Show percentage and visual progress bar
f"### {SI.LOADING} Processing Stage 3/7 (43%)\n\n"
f"Diarization in progress...\n\n"
f"```\n"
f"[████████░░░░░░░░] 43% | Est. 12 min remaining\n"
f"```"

Alternative: Use Gradio's built-in progress tracking:

from tqdm import tqdm
for i in tqdm(range(steps), desc="Processing"):
    # Gradio automatically shows progress bar with tqdm
    process_step(i)

Impact: Users can't estimate completion time; may abandon long-running tasks Priority: 🟡 MEDIUM Effort: Medium (2-3 days to integrate with backend)


6. Missing Success Animations/Confirmations

Location: All completion states across tabs

Issue: When operations complete, there's no celebratory feedback

Current State: Just text change from "Processing" to "Complete"

Improvement Needed:

  • Add ✨ animation or ✓ checkmark with fade-in effect
  • Show toast notification at top of screen
  • Play subtle success sound (optional, with mute toggle)
  • Temporarily highlight the results section with green border pulse

Example CSS Animation:

@keyframes success-pulse {
    0% { border-color: #10b981; box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7); }
    50% { box-shadow: 0 0 0 10px rgba(16, 185, 129, 0); }
    100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0); }
}

.success-animation {
    animation: success-pulse 1s ease-out;
}

Impact: Feels unpolished; users miss completion notification especially for background tabs Priority: 🟢 LOW Effort: Low (1 day)


🎨 Visual Design & Consistency

7. No Dark Mode Support

Location: src/ui/theme.py:27-33 defines dark colors but no toggle File Reference: src/ui/theme.py

Issue: Dark mode colors defined but never used

Current Code:

# Dark mode neutrals
"dark_background": "#0f172a",
"dark_surface": "#1e293b",
"dark_surface_elevated": "#334155",
"dark_border": "#334155",
"dark_text_primary": "#f1f5f9",
"dark_text_secondary": "#cbd5e1",
# ... all defined but unused!

Improvement Needed:

  • Add dark mode toggle in Settings & Tools tab
  • Use CSS media query @media (prefers-color-scheme: dark)
  • Persist user preference in localStorage or config file
  • Apply dark theme CSS to all tabs and components
  • Update event log styling (already dark) to be consistent

Example Implementation:

# In settings tab
dark_mode_toggle = gr.Checkbox(
    label="Enable Dark Mode",
    value=False,
    info="Toggle between light and dark theme"
)

# Add CSS that responds to a class toggle
blocks.css += """
.dark-mode {
    background: #0f172a;
    color: #f1f5f9;
}
/* ... more dark mode styles */
"""

Impact: Poor experience for users preferring dark mode; eye strain for night usage Priority: 🟡 MEDIUM Effort: Medium (2-3 days to implement properly)


8. Inconsistent Button Sizing

Location: Throughout all tabs

Examples:

  • src/ui/characters_tab_modern.py:132: size="sm" for "Refresh List"
  • src/ui/characters_tab_modern.py:127: No size specified for "View Character Overview"
  • src/ui/process_session_components.py:334: size="lg" for "Start Processing"

Issue: Buttons use size="sm", "md", "lg" inconsistently, creating visual hierarchy confusion

Improvement Needed: Establish clear button hierarchy and document in design system:

Action Type Size Example
Primary actions lg Start Processing, Save Campaign, Submit
Secondary actions md View Details, Export, Import
Utility actions sm Refresh, Copy, Clear

Audit Results:

  • Process Session: Mixed (lg, md, sm all used)
  • Characters: Mostly sm
  • Settings: Mostly sm
  • Campaign: sm only

Impact: Visual inconsistency; unclear action hierarchy confuses users Priority: 🟢 LOW Effort: Low (2-3 hours for audit and fixes)


9. Empty States Lack Visual Appeal

Location:

  • src/ui/campaign_tab_modern.py:40-53 (campaign overview empty state)
  • src/ui/characters_tab_modern.py:78-82 (characters empty state)
  • src/ui/stories_output_tab_modern.py:30-35 (session library empty state)

Issue: Empty states are plain text, not engaging or helpful

Current State:

StatusMessages.info(
    "No Campaign Selected",
    "Select a campaign above or load one from the Campaign Launcher to see campaign metrics."
)

Improvement Needed:

  • Add SVG illustrations or Unicode icons (📂, 🎭, 📖, 🎲, ⚔️)
  • Use centered layout with larger, more prominent text
  • Add call-to-action button ("Create Your First Campaign", "Process a Session", etc.)
  • Show helpful tips, feature highlights, or tutorial links
  • Use cards/containers to make empty states visually distinct

Example Implementation:

gr.Markdown(
    """
    <div style="text-align: center; padding: 3rem;">
        <div style="font-size: 4rem; margin-bottom: 1rem;">🎭</div>
        <h2>No Campaign Selected</h2>
        <p style="color: #6b7280; margin-bottom: 1.5rem;">
            Select a campaign from the launcher above to view metrics, characters, and session history.
        </p>
    </div>
    """
)
# Add action button below
create_campaign_btn = gr.Button("Create Your First Campaign", variant="primary")

Impact: First-time users feel lost; unclear what actions to take Priority: 🟡 MEDIUM Effort: Low (1 day for all empty states)


📝 Form Validation & Input Feedback

10. No Real-Time Input Validation

Location: src/ui/process_session_components.py:182-186 (session_id_input) File Reference: src/ui/process_session_tab_modern.py:79 (SESSION_ID_PATTERN)

Issue: Session ID has pattern requirements but no live validation

Current State:

SESSION_ID_PATTERN = re.compile(r"^[A-Za-z0-9_-]+$")
# Pattern exists but validation only happens on submit

Improvement Needed:

  • Add on_change handler to validate session ID as user types
  • Show ✓ green checkmark when valid
  • Show ✗ red X with error message when invalid
  • Highlight invalid characters in red
  • Show live example: "session_001 ✓" vs "session#@! ✗ Invalid characters: # @"

Example Implementation:

def validate_session_id(session_id: str):
    if not session_id:
        return "⚠️ Session ID required"
    if not SESSION_ID_PATTERN.match(session_id):
        invalid_chars = ''.join(set(c for c in session_id if not c.isalnum() and c not in '_-'))
        return f"✗ Invalid characters: {invalid_chars}"
    return f"✓ Valid session ID"

session_id_input.change(
    fn=validate_session_id,
    inputs=[session_id_input],
    outputs=[session_id_status]
)

Impact: Users submit forms and get errors; frustrating trial-and-error experience Priority: 🔴 HIGH Effort: Low (1 day for all validated inputs)


11. File Upload Missing Drag-and-Drop

Location: src/ui/process_session_components.py:120-123 (audio_input)

Issue: File upload requires clicking, no drag-drop support visible

Current State:

components["audio_input"] = gr.File(
    label="Session Audio File",
    file_types=[".m4a", ".mp3", ".wav", ".flac"],
)

Improvement Needed:

  • Verify drag-and-drop works (Gradio supports this by default, but may need CSS enhancement)
  • Add visual feedback: "Drop file here" overlay when dragging over zone
  • Display file icon, name, size after drop
  • Show file format validation inline with color coding
  • Add "or click to browse" text

Enhanced CSS:

.file-upload {
    border: 2px dashed #d1d5db;
    border-radius: 12px;
    padding: 3rem;
    text-align: center;
    transition: all 0.2s;
    background: #f9fafb;
}

.file-upload:hover,
.file-upload.drag-over {
    border-color: #6366f1;
    background: #f0f1ff;
}

.file-upload::before {
    content: "📁 Drag & drop your audio file here\nor click to browse";
    font-size: 1.1rem;
    color: #6b7280;
}

Impact: Slower workflow, especially for power users processing multiple sessions Priority: 🟡 MEDIUM Effort: Low (1 day for CSS enhancements)


12. No Character Count on Long Textareas

Location: src/ui/process_session_components.py:220-230

Issue: Character names and player names inputs don't show length or limits

Current State:

components["character_names_input"] = gr.Textbox(
    label="Character Names (comma-separated)",
    placeholder=Placeholders.CHARACTER_NAME,
    info="Used when Manual Entry is selected.",
)

Improvement Needed:

  • Add character counter below textareas: "42/500 characters"
  • Show warning at 80% capacity: "407/500 characters ⚠️"
  • Show error when exceeding limit
  • Add word count for narrative fields
  • Show item count for comma-separated lists: "4 characters entered"

Example Implementation:

def count_characters(text: str) -> str:
    length = len(text)
    items = len([x.strip() for x in text.split(',') if x.strip()])
    if length > 400:
        return f"⚠️ {length}/500 characters | {items} items"
    return f"{length}/500 characters | {items} items"

character_names_input.change(
    fn=count_characters,
    inputs=[character_names_input],
    outputs=[char_counter_display]
)

Impact: Users unknowingly truncate data or don't know field limits Priority: 🟢 LOW Effort: Low (1 day)


🔍 Search & Discovery

13. Session Search Missing Debouncing

Location: src/ui/stories_output_tab_modern.py:60-64

Issue: Search triggers immediately on button click; no search-as-you-type with debouncing

Current State:

search_button.click(
    fn=handle_search,
    inputs=[search_query],
    outputs=[search_results_df, search_no_results_md]
)

Improvement Needed:

  • Add debouncing (300ms delay after typing stops)
  • Show "Searching..." indicator while processing
  • Add search-as-you-type option (with debounce)
  • Cache recent searches in session state
  • Show search result count: "Found 42 results in 8 sessions"
  • Add "Clear" button to reset search
  • Highlight search terms in results

Example Implementation:

# Use Gradio's built-in debouncing (simple and safe)
search_query.change(
    fn=handle_search,
    inputs=[search_query],
    outputs=[search_results_df, search_no_results_md],
    debounce=0.3  # 300ms delay - built-in Gradio feature
)

Impact: Poor search experience; potential performance issues with large datasets Priority: 🟡 MEDIUM Effort: Medium (2 days)


14. Tables Not Sortable or Filterable

Location: src/ui/characters_tab_modern.py:96-103 (char_table)

Issue: Character table can't be sorted by columns; large campaigns become unwieldy

Current State:

char_table = gr.Dataframe(
    headers=["Character", "Player", "Race/Class", "Level", "Sessions"],
    datatype=["str", "str", "str", "number", "number"],
    label="Characters",
    interactive=False,  # ← Not sortable!
    wrap=True,
)

Improvement Needed:

  • Make interactive=True to enable column sorting
  • Add filter/search box above table
  • Enable column resizing
  • Add pagination for 50+ rows
  • Highlight row on hover with background color change
  • Allow clicking row to select and auto-populate dropdown

Example Implementation:

char_table = gr.Dataframe(
    headers=["Character", "Player", "Race/Class", "Level", "Sessions"],
    datatype=["str", "str", "str", "number", "number"],
    label="Characters",
    interactive=True,  # ✓ Enable sorting
    wrap=True,
    row_count=(10, "dynamic"),  # Enable pagination
    col_count=(5, "fixed"),
)

Impact: Hard to find specific characters in campaigns with 10+ characters Priority: 🟡 MEDIUM Effort: Low (1 day)


⚙️ Settings & Configuration

15. No Auto-Save Indicators

Location: src/ui/settings_tools_tab_modern.py:87-97 (save buttons)

Issue: After clicking "Save API Keys", no visual confirmation of save state persistence

Current State: Button just updates status markdown once

Improvement Needed:

  • Show button state transitions:
    1. Save API Keys (initial)
    2. Saving... (processing)
    3. Saved ✓ (success, 2s duration)
    4. Back to Save API Keys
  • Add persistent status badge at top: ⚙️ All settings saved vs ⚠️ Unsaved changes
  • Highlight changed fields with orange border
  • Add "Discard Changes" button to revert
  • Show last saved timestamp: "Last saved: 2 minutes ago"

Example Implementation:

def save_api_keys_with_feedback(groq_key, openai_key, hf_key):
    # Button state 1: Saving
    yield gr.update(value="Saving...", interactive=False)

    # Save
    ConfigManager.save_api_keys(groq_key, openai_key, hf_key)

    # Button state 2: Saved (temporary)
    yield gr.update(value="Saved ✓", variant="secondary")
    time.sleep(2)

    # Button state 3: Reset
    yield gr.update(value="Save API Keys", interactive=True, variant="primary")

Impact: Users uncertain if settings persisted; may save multiple times Priority: 🟡 MEDIUM Effort: Medium (2 days for all save operations)


16. Missing Confirmation Dialogs ✅ COMPLETE

Status:Draft PR #144 (2025-11-25) - Ready for Merge Branch: feature-UI-16-confirmation-modals Files Modified: 2 files (+122, -4 lines) Location: src/ui/settings_tools_tab_modern.py:386-391 (restart_app_btn)

Completed State:

  • ✅ Custom confirmation modal system with mandatory checkbox for acknowledgment
  • ✅ 5-second countdown timer before execution (prevents accidental clicks)
  • ✅ Implemented for critical actions:
    • Restart Application (prevents app shutdown during processing)
    • Clear All Conversations (prevents data loss)
  • ✅ Gracefully handled non-existent actions (Delete Character, Reset Configuration - correctly skipped)
  • ✅ Protection against accidental data loss and workflow interruption

Note: Author manually verified functionality (Playwright environment issue prevented screenshots)

Original Issue: Critical actions like "Restart Application" have no confirmation dialog

Current Code:

restart_app_btn = UIComponents.create_action_button(
    "🔄 Restart Application", variant="secondary", size="md"
)
# Clicking this kills the app immediately with no confirmation!

Improvement Needed:

  • Add confirmation modal: "Are you sure? Active sessions will be terminated."
  • Require checkbox: "☐ I understand this will stop all processing"
  • Add countdown: "Restarting in 5... 4... 3..." with cancel button
  • Show warning badge on button: ⚠️ icon

Other Actions Needing Confirmation:

  • Deleting character profiles
  • Clearing event logs
  • Resetting configuration to defaults
  • Overwriting existing session files

Example Implementation:

# Add confirmation checkbox
restart_confirm = gr.Checkbox(
    label="I understand this will terminate all active processing",
    value=False
)

def restart_with_confirmation(confirmed):
    if not confirmed:
        return StatusMessages.warning(
            "Confirmation Required",
            "Please check the confirmation box before restarting."
        )
    # Proceed with restart
    restart_application()

restart_app_btn.click(
    fn=restart_with_confirmation,
    inputs=[restart_confirm],
    outputs=[restart_status]
)

Impact: Accidental clicks cause data loss and workflow interruption Priority: 🔴 HIGH Effort: Medium (2 days for all critical actions)


17. Accordion State Not Persisted

Location: All accordions across tabs

  • src/ui/process_session_components.py:233, 268 (Advanced Backend Settings, Skip Options)
  • src/ui/settings_tools_tab_modern.py:61, 99, 157, 234, 274, 356 (6 accordions)

Issue: User opens "Advanced Settings" accordion, navigates away, returns → it's closed again

Current State: All accordions default to open=False on every page load

Improvement Needed:

  • Save accordion state to localStorage or session state: {"advanced_backend_settings": true}
  • Restore state on page load/tab switch
  • Add "Expand All" / "Collapse All" buttons for sections with 3+ accordions
  • Consider making frequently-used accordions open=True by default

Example Implementation:

# JavaScript to persist state
accordion_persistence_js = """
<script>
document.addEventListener('DOMContentLoaded', function() {
    const accordions = document.querySelectorAll('details');

    // Restore state
    accordions.forEach((acc, idx) => {
        const key = `accordion_state_${idx}`;
        const saved = localStorage.getItem(key);
        if (saved === 'open') acc.open = true;
    });

    // Save state on toggle
    accordions.forEach((acc, idx) => {
        acc.addEventListener('toggle', () => {
            localStorage.setItem(`accordion_state_${idx}`, acc.open ? 'open' : 'closed');
        });
    });
});
</script>
"""

Impact: Repetitive clicking wastes time, especially in Settings tab Priority: 🟢 LOW Effort: Low (1 day)


🧭 Navigation & Workflow

18. No Breadcrumbs or Progress Persistence

Location: src/ui/process_session_components.py:68-94 (workflow stepper)

Issue: Workflow stepper is static HTML; doesn't update based on actual progress

Current State:

<div class="stepper">
    <div class="step active">
        <div class="step-number">1</div>
        <div class="step-label">Upload</div>
    </div>
    <!-- Always shows step 1 as active -->
</div>

Improvement Needed: Make stepper dynamic and interactive:

  1. Update based on form state:

    • Step 1 active when no file uploaded
    • Step 2 active when file uploaded but not configured
    • Step 3 active when configuration complete
    • Step 4 active when processing done
  2. Visual improvements:

    • Add checkmarks ✓ to completed steps
    • Gray out incomplete steps
    • Pulse animation on current step
  3. Interactive navigation:

    • Make steps clickable to jump between sections
    • Scroll to relevant section when clicked
    • Validate before allowing forward navigation
  4. Progress persistence:

    • Show current step in browser tab title: "(Step 2/4) Configure Session | D&D Processor"
    • Save progress in session state
    • Allow resuming from last step

Example Implementation:

def update_stepper(audio_file, session_id, config_complete, processing_done):
    if processing_done:
        current_step = 4
    elif config_complete:
        current_step = 3
    elif session_id and audio_file:
        current_step = 2
    elif audio_file:
        current_step = 2
    else:
        current_step = 1

    return generate_stepper_html(current_step)

# Wire to relevant inputs
audio_input.change(fn=update_stepper, ...)
session_id_input.change(fn=update_stepper, ...)

Impact: Users lose track of progress in long workflow; unclear what to do next Priority: 🟡 MEDIUM Effort: Medium (2-3 days)


19. Missing Copy Functionality

Location: src/ui/helpers.py:212-228 defines create_copy_button() but it's never used

Issue: Copy button helper exists but copy-to-clipboard not implemented anywhere

Current Code:

@staticmethod
def create_copy_button(target_component) -> gr.Button:
    """Create a copy-to-clipboard button for a text component."""
    return gr.Button("Copy", size="sm", variant="secondary", scale=0)
    # But no .click() handlers wire it up anywhere!

Improvement Needed: Add copy buttons next to:

  • ✅ Session ID (after processing completes)
  • ✅ Full transcript textbox
  • ✅ IC/OOC transcript textboxes
  • ✅ Event log
  • ✅ API configuration examples
  • ✅ Character profile JSON
  • ✅ Error messages/stack traces

Features:

  • Show "Copied!" tooltip for 2 seconds after click
  • Use Gradio's built-in show_copy_button=True parameter where available
  • Fall back to JavaScript clipboard API for custom components

Example Implementation:

# For textboxes, use built-in feature
full_output = gr.Textbox(
    label="Full Transcript",
    lines=10,
    show_copy_button=True  # ✓ Built-in Gradio feature
)

# For custom copy buttons
copy_session_id_btn = UIComponents.create_copy_button(session_id_output)

def copy_to_clipboard(text):
    # Return updated button state
    yield gr.update(value="Copied!", variant="secondary")
    time.sleep(2)
    yield gr.update(value="Copy", variant="secondary")

copy_session_id_btn.click(
    fn=copy_to_clipboard,
    inputs=[session_id_output],
    outputs=[copy_session_id_btn]
)

Impact: Users manually select and copy large text blocks; slower workflow Priority: 🟢 LOW Effort: Low (1 day)


🎯 Feature Gaps

20. No Tooltips Despite CSS Support

Location: src/ui/theme.py:244-263 defines .info-icon class but it's never used

Issue: CSS ready for info tooltips but not implemented in UI

Current CSS:

.info-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #e5e7eb;
    color: #6b7280;
    font-size: 12px;
    font-weight: 600;
    cursor: help;
    margin-left: 0.5rem;
}

.info-icon:hover {
    background: #6366f1;
    color: white;
}
/* CSS exists but no HTML uses this class! */

Improvement Needed: Add ℹ️ tooltips next to complex or technical fields:

High Priority Fields:

  • "Expected Speakers": "Helps diarization accuracy. Typical D&D table: 3-5 players + 1 DM = 4-6 speakers"
  • "Skip Diarization": "⚠️ All segments will be labeled UNKNOWN. Only use for testing or single-speaker recordings."
  • "Classification Backend":
    • Ollama: Fast, free, local (requires setup)
    • Groq: Fast, cloud API (costs per token)
    • Colab: Free GPU, slower (requires Google account)
  • "Chunk Length": "Longer chunks = faster processing but higher memory usage. Recommended: 300-600s"
  • "Run Pipeline Until": "Stop at intermediate stages to save time or test specific steps"

Implementation Options:

# Option 1: Using Gradio's info parameter (already used)
gr.Slider(
    label="Expected Speakers",
    info="Helps diarization accuracy. Typical table is 3 players + 1 DM.",  # ✓ Already used
)

# Option 2: Custom HTML with info icon
gr.HTML("""
<div style="display: flex; align-items: center;">
    <label>Expected Speakers</label>
    <span class="info-icon" title="Helps diarization accuracy...">ℹ️</span>
</div>
""")

# Option 3: Markdown with collapsible details
gr.Markdown("""
**Expected Speakers**
<details><summary>ℹ️ What does this do?</summary>
Helps the diarization model identify different speakers...
</details>
""")

Impact: Users confused by technical options; make wrong choices; contact support Priority: 🟡 MEDIUM Effort: Medium (2 days to write helpful tooltips for all fields)


📊 Summary by Priority

Priority Breakdown

Priority Count Improvements
🔴 HIGH 5 #1 (ARIA labels), #2 (Keyboard nav), #4 (Loading states), #10 (Input validation), #16 (Confirmations)
🟡 MEDIUM 10 #3, #5, #7, #9, #11, #13, #14, #15, #18, #20
🟢 LOW 5 #6, #8, #12, #17, #19

Effort Breakdown

Effort Count Total Days Improvements
Low 10 ~10 days #3, #4, #6, #8, #9, #10, #11, #12, #17, #19
Medium 8 ~16 days #1, #5, #7, #13, #15, #16, #18, #20
High 1 ~4-5 days #2 (keyboard nav)

Total Estimated Effort: 30-31 days for all improvements


🚀 Quick Wins

High Impact + Low Effort (Recommended First Phase)

# Improvement Effort Impact Priority
4 Add loading spinners to buttons 1 day Prevents double-clicks, clear feedback 🔴 HIGH
10 Real-time session ID validation 1 day Reduces form errors, better UX 🔴 HIGH
3 Add focus indicators 1 day Accessibility compliance 🟡 MEDIUM
19 Wire up copy buttons 1 day Faster workflows 🟢 LOW
8 Fix button sizing consistency 0.5 day Visual polish 🟢 LOW
9 Improve empty states 1 day Better onboarding 🟡 MEDIUM

Total Quick Wins: ~5.5 days, 6 improvements completed


📋 Implementation Roadmap

Phase 1: Critical Fixes (2 weeks)

  • ✅ #4 - Button loading states
  • ✅ #10 - Real-time input validation
  • ✅ #16 - Confirmation dialogs
  • ✅ #1 - ARIA labels (basic implementation)

Phase 2: User Experience (2 weeks)

  • ✅ #5 - Progress percentages
  • ✅ #3 - Focus indicators
  • ✅ #9 - Empty state improvements
  • ✅ #15 - Auto-save indicators
  • ✅ #20 - Tooltips for complex fields

Phase 3: Polish & Advanced (2-3 weeks)

  • ✅ #7 - Dark mode
  • ✅ #18 - Dynamic workflow stepper
  • ✅ #13 - Debounced search
  • ✅ #14 - Sortable tables
  • ✅ #2 - Keyboard shortcuts (partial)

Phase 4: Nice-to-Have (1 week)

  • ✅ #6 - Success animations
  • ✅ #8 - Button consistency audit
  • ✅ #11 - Enhanced drag-drop
  • ✅ #12 - Character counters
  • ✅ #17 - Accordion persistence
  • ✅ #19 - Copy functionality

🧪 Testing Checklist

After implementing improvements, test:

  • Accessibility: Run Lighthouse audit, achieve 90+ accessibility score
  • Keyboard Navigation: Complete full workflow using only keyboard
  • Screen Reader: Test with NVDA/JAWS, verify all labels readable
  • Mobile: Test on tablet/mobile viewports (responsive design)
  • Dark Mode: Verify all components readable in both themes
  • Browser Compatibility: Test on Chrome, Firefox, Safari, Edge
  • Performance: Verify no loading state regressions
  • Error Handling: Test all validation with invalid inputs

📚 References

Files Analyzed:

  • src/ui/process_session_tab_modern.py (156 lines)
  • src/ui/process_session_components.py (579 lines)
  • src/ui/campaign_tab_modern.py (72 lines)
  • src/ui/characters_tab_modern.py (405 lines)
  • src/ui/settings_tools_tab_modern.py (448 lines)
  • src/ui/stories_output_tab_modern.py (70 lines)
  • src/ui/theme.py (500 lines)
  • src/ui/helpers.py (281 lines)

Total Lines Analyzed: ~2,500+ lines of UI code

Technologies:

  • Gradio 4.0+ (Python web UI framework)
  • Custom CSS (500+ lines)
  • Markdown rendering
  • File upload/download
  • Real-time updates with timers

Document Version: 1.0 Last Updated: 2025-11-16 Author: UI Analysis Agent