# Design Guidelines — Accessible Video Processing Platform **Document Version:** 1.0 **Date:** 2026-05-01 **Status:** Active --- ## Quick Navigation - [Docs Hub](../README.md) - [Architecture](architecture.md) - [Tech Stack](tech_stack.md) - [API Spec](api_spec.md) ## 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](architecture.md), [Tech Stack](tech_stack.md) | | 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:** ```text ┌─────────────────────────────────────┐ │ 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 ```text ``` 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:hidden` control) - 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: `