Accessibility

Last updated on 2026-04-05

The NeuralDesk AI Ops Dashboard is built with WCAG 2.1 AA accessibility from the ground up. Every screen -- from the model registry table to the prompt playground -- supports keyboard navigation, screen readers, and reduced motion preferences.

Accessibility Hooks

Five custom hooks in the hooks/ directory provide reusable accessibility patterns:

use-announce

Announces dynamic content changes to screen readers using an ARIA live region.

import { useAnnounce } from "@/hooks/use-announce"

function ModelDeployment() {
  const announce = useAnnounce()

  function handleDeploy(modelName: string) {
    // ... deployment logic
    announce(`${modelName} has been deployed to production`)
  }
}

use-focus-trap

Traps keyboard focus within a container (modals, dialogs, sheets). Focus cycles through focusable elements and returns to the trigger element on close.

import { useFocusTrap } from "@/hooks/use-focus-trap"

function ApiKeyDialog({ isOpen }: { isOpen: boolean }) {
  const ref = useFocusTrap(isOpen)
  return <div ref={ref}>...</div>
}

use-keyboard-navigation

Provides arrow key navigation for lists, grids, and custom widgets.

import { useKeyboardNavigation } from "@/hooks/use-keyboard-navigation"

function LogTable({ logs }: Props) {
  const { activeIndex, handleKeyDown } = useKeyboardNavigation(logs.length)
  return <div onKeyDown={handleKeyDown}>...</div>
}

use-reduced-motion

Detects the user's prefers-reduced-motion media query setting. Chart animations and playground transitions are disabled when this preference is active.

import { useReducedMotion } from "@/hooks/use-reduced-motion"

function TokenUsageChart() {
  const prefersReducedMotion = useReducedMotion()
  return <AreaChart isAnimationActive={!prefersReducedMotion} ... />
}

use-mobile

Detects mobile viewport breakpoints for responsive UI adjustments.

import { useMobile } from "@/hooks/use-mobile"

function Sidebar() {
  const isMobile = useMobile()
  // Render sheet on mobile, fixed sidebar on desktop
}

Accessibility Components

Every page includes a skip navigation link that becomes visible on first Tab press, allowing keyboard users to bypass the sidebar and header.

import { SkipLink } from "@/components/a11y/skip-link"
// Rendered in the root layout, targets #main-content

Live Region

An ARIA live region component for announcing dynamic content changes.

import { LiveRegion } from "@/components/a11y/live-region"

Visually Hidden

Provides text content for screen readers without visual display.

import { VisuallyHidden } from "@/components/a11y/visually-hidden"

<button>
  <TrashIcon />
  <VisuallyHidden>Delete API key</VisuallyHidden>
</button>

Keyboard Navigation

All interactive elements are keyboard accessible:

Element Keys
Sidebar navigation Tab, Arrow Up/Down, Enter
Model registry table Tab through rows, Arrow Up/Down to navigate, Enter to expand
Prompt library table Tab through rows, Enter to view details
Log table Tab through rows, Enter to expand detail panel
Error list Tab through items, Enter to view error detail
Playground editor Standard text editing keys, Tab for indentation
Playground model selector Arrow Up/Down to select, Enter to confirm
Parameter sliders Arrow Left/Right to adjust, Home/End for min/max
Dialog/Sheet Tab cycles within, Escape to close
Team member actions Tab to action buttons, Enter/Space to activate

Color Contrast

All text and interactive elements meet WCAG AA contrast ratios (4.5:1 for normal text, 3:1 for large text) in both light and dark modes. The oklch color system ensures perceptually uniform contrast across the palette. Status badges (deployed/green, error/red, warning/yellow) maintain sufficient contrast against both light and dark backgrounds.

Touch Targets

All interactive elements have a minimum touch target size of 44x44px, meeting WCAG 2.1 success criterion 2.5.5.

Testing Recommendations

  • Screen reader: Test with VoiceOver (macOS) or NVDA (Windows)
  • Keyboard: Navigate the entire app without a mouse -- pay special attention to the playground editor and parameter sliders
  • Color contrast: Use the browser DevTools accessibility panel
  • Reduced motion: Enable "Reduce motion" in system preferences and verify chart animations are disabled

Need a professional accessibility review? We run audits for Next.js and React apps starting at $499.