Accessibility
Last updated on 2026-09-07
The kit is built with WCAG AA accessibility as a baseline. Every component, from the Kanban board to data tables, analytics charts, and form dialogs, follows accessible patterns.
Accessibility Features
Keyboard Navigation
- All interactive elements are keyboard-accessible
- Tab order follows logical reading order
- Focus indicators are visible on all focusable elements via the global
:focus-visiblestyle::focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } - Dialogs and sheets trap focus and return it on close
- The Kanban board supports keyboard reordering as a fallback to drag-and-drop
- Data tables have focusable rows with keyboard-accessible action menus
- Filter dropdowns, label pickers, and date pickers are fully keyboard-operable
- The sidebar navigation is fully keyboard-navigable
Screen Reader Support
- Semantic HTML throughout:
<nav>,<main>,<article>,<section> - One
<h1>per page with no heading level skips; board pages use<h1 class="sr-only">Board</h1>to provide a screen-reader-only heading - All images have descriptive
alttext - Icon-only buttons have
aria-labelattributes - Form fields have associated
<label>elements - Validation errors use
aria-invalidandaria-describedby - Kanban columns announce their status name and task count
- Status changes via drag-and-drop are confirmed via toast notifications (announced as live regions by Sonner)
- Data tables use proper
<thead>,<tbody>, and<th>elements withscopeattributes - Breadcrumb navigation uses the
<nav>element with properBreadcrumbListsemantics
Color and Contrast
- All text meets WCAG AA contrast ratio (4.5:1 for normal text, 3:1 for large text)
- Status indicators use color + text + icon (never color alone):
- Task statuses display both a colored dot and a text label
- Priority levels use both color and text (e.g., "Urgent" with red indicator)
- Capacity badges use icon + text + background color (e.g., AlertTriangle icon + "Over capacity")
- Pipeline stage badges include text labels alongside color indicators
- Both light and dark themes maintain contrast compliance
- Focus rings are visible against all backgrounds
Reduced Motion
The kit respects prefers-reduced-motion with a global rule that disables all animations:
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
This affects:
- Kanban card drag animations
- Fade-in-up page entrance animations
- Scale-in card animations
- Float animations
- Shimmer loading animations
- Toast notification slide-in animations
- Chart transitions
- Button press micro-interactions
- Stagger delay utilities
Touch Targets
- All interactive elements meet the 44x44px minimum touch target size
- Small visual elements (label pills, priority flags, action dots) use padding to increase the touch area
- Calendar day cells and filter buttons use
min-h-11 px-3for comfortable touch - The
.touch-targetutility class is available for enforcing minimum dimensions:.touch-target { min-width: 44px; min-height: 44px; }
Skip Link
Every page includes a skip-to-content link (SkipLink component imported in app/layout.tsx) that becomes visible on focus, allowing keyboard users to bypass the sidebar navigation:
.skip-link {
position: absolute;
top: -100%;
left: 50%;
transform: translateX(-50%);
z-index: 100;
padding: 0.75rem 1.5rem;
background: var(--primary);
color: var(--primary-foreground);
border-radius: var(--radius);
font-weight: 600;
}
.skip-link:focus {
top: 1rem;
outline: 2px solid var(--ring);
outline-offset: 2px;
}
Screen Reader Utilities
The .sr-only class is used for content that should be accessible to screen readers but visually hidden:
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
}
This is used for:
- Board page headings (
<h1 class="sr-only">Board</h1>) - Task detail page headings (
<h1 class="sr-only">{task.title}</h1>) - Descriptive labels on icon-only actions
Form Accessibility
Forms are used extensively for creating tasks, cycles, modules, goals, pages, and labels:
- Required fields are marked with appropriate labels
- Validation errors appear inline below the field
- Error fields have
aria-invalid="true"and link to error text viaaria-describedby - Submit buttons show loading state during async operations (via
useTransition) - The
FormDialogcomponent wraps forms in a dialog with proper focus management - Date inputs use native HTML
<input type="date">for maximum accessibility
Kanban Board Accessibility
The drag-and-drop Kanban board is designed for inclusivity:
- Each task card is focusable
- Column headers display the status name and task count
- Drag-and-drop is powered by
@hello-pangea/dndwhich provides keyboard drag support out of the box (Space to lift, arrow keys to move, Space to drop) - Status changes via drag are confirmed via toast notifications (Sonner's toast is announced as a live region)
- The task detail page provides select dropdowns as an alternative to drag-and-drop for changing status
Data Table Accessibility
Tables throughout the kit (backlog, cycles, team contribution, workload) follow table best practices:
- Proper
<Table>,<TableHeader>,<TableHead>,<TableBody>,<TableRow>,<TableCell>elements - Sortable table headers are keyboard-accessible
- Action menus are keyboard-accessible
- Status badges use icon + text, not color alone
- Pagination controls are keyboard-accessible with descriptive labels
Chart Accessibility
Analytics charts include accessibility considerations:
- Charts have descriptive
CardTitleelements that serve as labels - Tooltips are keyboard-accessible via focus on data points
- The Team Contribution data table is provided alongside charts for screen reader users
- Chart colors maintain sufficient contrast between series
- Legends are provided for all multi-series charts