- Help.tsx: role tabs, TOC scroll-spy, search, lightbox, react-markdown renderer
- 7 markdown guides (global, client, linguist, reviewer, production, PM, admin)
with explicit click/drag/keyboard annotations throughout
- Sidebar: Help button added at bottom of nav (all roles)
- App.tsx: /help route, no RoleGate
- frontend/public/help-screenshots/{role}/: directories ready for screenshots
- tools/capture-help-screenshots.ts: Playwright screenshot script
- Clicks "Local login" toggle before filling credentials
- Uses test-admin local account (not SSO)
- backend/scripts/seed_test_users.py: idempotent MongoDB seed script
creates 6 local-auth users (admin + 5 roles) for capture + local dev
- .env.screenshots.example: template with test-admin credentials
- Removes docs/video_accessibility_user_guide_v3.md (superseded by in-app guides)
- Deps: react-markdown, remark-gfm, rehype-raw added to frontend
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
12 KiB
Design Guidelines — Accessible Video Processing Platform
Document Version: 1.0 Date: 2026-05-01 Status: Active
Quick Navigation
Agent Entry
| Signal | Value |
|---|---|
| Purpose | Visual system, accessibility rules, and UI consistency expectations for the React 19 frontend |
| Read When | You need design constraints, token definitions, component patterns, or accessibility guidance |
| Skip When | You only need implementation code or backend/system contracts |
| Canonical | Yes |
| Next Docs | Architecture, Tech Stack |
| Primary Sources | frontend/src/components/, frontend/src/styles/index.css, frontend/tailwind.config.js |
1. Design Approach
1.1 Design Philosophy
Clean, professional accessibility-first SaaS platform. The interface prioritises clarity and information hierarchy to support complex multi-language workflows for production teams, QC reviewers, and clients. Dark sidebar + light main content area is the primary shell pattern.
1.2 Stack
| Layer | Choice |
|---|---|
| CSS framework | Tailwind CSS v4 (utility-first, no component library) |
| Icon system | Inline SVG (24×24 standard, 16×16 compact) |
| Component pattern | Custom React 19 functional components with TypeScript |
| State (server) | TanStack Query v5 |
| State (client) | Zustand v5 |
2. Core Design Elements
2.1 Typography
Font Families:
| Role | Font | Weights | Usage |
|---|---|---|---|
| Primary / Body | Inter | 400, 500, 600 | All UI text |
| Fallback | system-ui, Avenir, Helvetica, Arial, sans-serif | — | When Inter unavailable |
Type Scale (Tailwind):
| Element | Class | Approx Size | Usage |
|---|---|---|---|
| Page title | text-xl font-semibold |
20px/700 | Navbar page heading |
| Section header | text-lg font-semibold |
18px/600 | Card / panel titles |
| Body | text-sm / text-base |
14–16px | Table cells, form labels |
| Caption / badge | text-xs font-medium |
12px/500 | Status badges, metadata |
Line Height: leading-normal (1.5) for body; leading-tight (1.25) for headings and compact UI.
2.2 Color System
Brand & Interactive:
| Purpose | Tailwind | Usage |
|---|---|---|
| Primary action | bg-gradient-to-r from-blue-500 to-blue-600 |
Primary CTAs (New Upload, submit) |
| Primary hover | hover:from-blue-600 hover:to-blue-700 |
Primary CTA hover state |
| Link / accent | #646cff |
Hyperlinks (global CSS) |
Semantic UI Colors:
| Purpose | Tailwind classes | Hex approx | Usage |
|---|---|---|---|
| Surface / background | bg-white |
#ffffff | Cards, main content |
| Sidebar / shell | bg-gray-900 or dark bg |
— | App shell sidebar |
| Navbar | bg-white shadow-sm border-b border-gray-200 |
#ffffff | Top navigation bar |
| Primary text | text-gray-900 |
#111827 | Headings, body |
| Secondary text | text-gray-600 |
#4B5563 | Labels, descriptions |
| Border | border-gray-200 |
#E5E7EB | Card borders, dividers |
| Hover bg | hover:bg-gray-100 |
#F3F4F6 | Button/row hover |
Status Badge Colors (semantic):
| State | Tailwind classes |
|---|---|
| created | bg-gray-100 text-gray-800 |
| ingesting / translating | bg-blue-100 text-blue-800 |
| ai_processing | bg-purple-100 text-purple-800 |
| pending_qc | bg-yellow-100 text-yellow-800 |
| completed | bg-green-100 text-green-800 |
| processing_failed / tts_failed | bg-red-100 text-red-800 |
| qc_feedback | bg-orange-100 text-orange-800 |
| pending_final_review | bg-orange-100 text-orange-800 |
| tts_generating | bg-indigo-100 text-indigo-800 |
| rendering_video / rendering_qc | bg-violet-100 text-violet-800 |
Source: frontend/src/utils/jobStatusMessages.ts — getJobStatusColor().
Color Accessibility: All status badge combinations (light bg / dark text) target WCAG 2.1 AA contrast (4.5:1 for text). Primary blue gradient on white meets 4.5:1 ratio.
2.3 Layout System
Spacing Primitives (Tailwind):
| Token | Value | Usage |
|---|---|---|
p-2 |
8px | Icon button padding |
px-4 py-2 |
16px / 8px | Compact button |
px-6 py-4 |
24px / 16px | Navbar padding |
space-x-4 |
16px | Horizontal item gap |
gap-6 |
24px | Grid gap |
Container Strategy:
| Container | Max Width | Context |
|---|---|---|
| Page shell | Full viewport | App layout |
| Main content | max-w-7xl (1280px) |
Dashboard, job lists |
| Narrow form | max-w-2xl (672px) |
Upload form, settings |
App Shell Pattern:
┌─────────────────────────────────────┐
│ Navbar (h-16, bg-white, shadow-sm) │
├────────────┬────────────────────────┤
│ Sidebar │ Main Content Area │
│ (w-64) │ (flex-1, scrollable) │
│ hidden │ │
│ on mobile │ │
└────────────┴────────────────────────┘
Grid System: 12-column Tailwind grid, responsive with grid-cols-1 md:grid-cols-2 lg:grid-cols-3.
2.4 Component Patterns
Navigation
| Component | Classes | Notes |
|---|---|---|
| Navbar | bg-white shadow-sm border-b border-gray-200 px-6 py-4 |
Fixed top, h-16 |
| Sidebar | w-64, hidden on < lg |
Role-filtered nav items with badge counts |
| Mobile toggle | p-2 text-gray-600 hover:bg-gray-100 rounded-lg |
Hamburger, lg:hidden |
| Active nav link | border-l-4 border-blue-500 bg-blue-50 text-blue-700 |
Left border indicator |
| Badge counter | bg-red-500 text-white text-xs rounded-full |
Pending QC / review counts |
Buttons
| Variant | Classes | Usage |
|---|---|---|
| Primary | bg-gradient-to-r from-blue-500 to-blue-600 text-white px-4 py-2 rounded-lg hover:from-blue-600 hover:to-blue-700 shadow-sm hover:shadow-md transition-all duration-200 |
Primary CTA, submit |
| Secondary | text-gray-600 hover:text-gray-900 hover:bg-gray-100 rounded-lg p-2 transition-colors |
Icon buttons, secondary actions |
| Destructive | bg-red-500 text-white hover:bg-red-600 |
Delete, reject actions |
Icon size in buttons: w-4 h-4 mr-2 (leading icon), w-6 h-6 (standalone icon button).
Status Badges
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {status-color-classes}">
See Status Badge Colors table above for the full mapping. Source: src/components/StatusBadge.tsx.
Forms
| Element | Classes |
|---|---|
| Input | border border-gray-300 rounded-lg px-4 py-3 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 |
| Label | text-sm font-medium text-gray-700 mb-2 |
| Error | text-red-500 text-sm mt-1 |
| Help text | text-gray-500 text-sm mt-1 |
Forms use react-hook-form v7 for validation. Min touch target: 44×44px.
Cards / Panels
| Element | Classes |
|---|---|
| Card | bg-white shadow-md rounded-lg border border-gray-200 p-6 |
| Hover | hover:shadow-lg transition-shadow duration-200 |
| Interactive | cursor-pointer hover:border-blue-300 |
Dropzone (Upload)
See src/components/UploadDropzone/. Uses react-dropzone v14. Pattern: dashed border + centered icon + instructional text + drag-active state change.
2.5 Responsive Behavior
Breakpoints (Tailwind defaults):
| Breakpoint | Min Width | Layout adaptation |
|---|---|---|
| default | 0px | Single column, sidebar hidden |
md |
768px | 2-column grids |
lg |
1024px | Sidebar visible, 3-column grids |
xl |
1280px | Full desktop layout |
Mobile adaptations:
- Sidebar: hidden, toggled by hamburger button (
lg:hiddencontrol) - Tables: horizontal scroll
- Navigation: mobile overlay panel
- Touch targets: min 44×44px on all interactive elements
3. Accessibility Guidelines
3.1 WCAG Compliance
Target: WCAG 2.1 Level AA — mandatory, as this platform produces accessibility assets for third parties.
| Criterion | Requirement |
|---|---|
| Contrast ratio (text) | ≥ 4.5:1 |
| Contrast ratio (UI components) | ≥ 3:1 |
| Focus visible | Visible focus ring on all interactive elements |
| Alt text | All informational images |
| Form labels | All inputs have associated labels |
3.2 Keyboard Navigation
- All interactive elements focusable via
Tab - Visible focus ring:
focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 - Logical tab order (top-to-bottom, left-to-right)
- Modal focus trap (Tab cycles within modal when open)
- Skip-to-main link for keyboard users
3.3 Screen Reader Support
- ARIA labels on icon-only buttons:
aria-label="Close dialog" - Semantic HTML:
<nav>,<main>,<article>,<aside> - Form
<label>elements associated viafor/id aria-live="polite"for toast/notification messages- Status updates announced to screen readers
3.4 Focus Management
- Focus returns to trigger element after dialog/modal close
- Error messages announced via
aria-live - Notification menu uses ARIA landmark roles
4. Role-Based UI Patterns
The UI adapts based on the authenticated user's role. Role-gated elements are controlled at component level via useAuthStore().
| Role | Visible UI |
|---|---|
client |
Jobs list (own jobs), New Upload, Downloads |
linguist / reviewer |
QC queue, VTT editor |
production |
All jobs, processing controls |
project_manager |
Briefs, final review queue, notifications |
admin |
All of the above + Admin panel, Org management |
Sidebar badges reflect pending work counts per role:
pending_qccount → linguist/reviewer/production/adminpending_final_reviewcount → project_manager/admin- Failed jobs count → production/admin
- Submitted briefs count → all roles
5. Page Layout Patterns
5.1 Dashboard
Fixed header + sidebar shell. Main area: KPI summary row → filterable jobs table with status badges → pagination. Layout: full-width table inside max-w-7xl container.
5.2 Job Detail / QC Review
Split panel: video player (left, 60%) + VTT editor (right, 40%). Approval/rejection actions pinned to bottom. Responsive: stacked on < lg.
5.3 Upload Form
Centred narrow container (max-w-2xl). Steps: dropzone → metadata form → language selection → submit. Uses react-dropzone + react-hook-form.
5.4 Admin / Settings
Full-width table layout. Tabs for sub-sections (Users, Organisations, TTS Settings). Tables use standard card wrapper.
6. Internationalisation
The platform supports 50+ target languages for the content it processes. The UI shell itself is English-only at present. No i18n library is currently used for the UI layer.
Maintenance
Last Updated: 2026-05-01
Update Triggers:
- New component added or removed from
src/components/ - Tailwind config changes (breakpoints, theme extensions)
- Color system changes
- Accessibility audit findings
- Role changes affecting navigation visibility
Verification:
- Status badge color table matches
getJobStatusColor()insrc/utils/jobStatusMessages.ts - Role-based UI section reflects current roles in
useAuthStore() - Color contrast ratios remain WCAG AA compliant
- Responsive breakpoints match Tailwind config
- Component patterns verified against actual component files in
src/components/