2.1.0

This release is about **speed and access**. Each screen now loads only its own data, with a skeleton while it arrives, so the admin opens in a fraction of the time it used to. Filters, search and grouping are kept in the address bar, which means a filtered view is a link you can send someone. **Accessibility went from 530 failures to zero**, checked automatically on every build against WCAG 2.2 AA rather than by hand.

  • Added Per-route data loading with skeleton loading states; the admin boots in a fraction of the time and fetches only what each screen needs
  • Added Filters, search, and grouping persist to the URL and survive reload; filtered views are shareable links
  • Added Toggle, ToggleRow, MediaPicker, InlineField, Tabs, and Lazy primitives complete the shared component library; every switch, media picker, tab strip, and table in the admin renders through one implementation
  • Added Automated WCAG 2.2 AA verification (axe-core) across every admin view, enforced in CI
  • Added Shared admin component library (Button, Field, Table, Card, Tabs, Skeleton, Spinner, confirm dialog, app-wide Modal and Toast) with existing admin screens migrated onto the primitives.
  • Changed All admin toggles use the settings-row layout with brand-color checked state
  • Changed Term list renders as grouped tables consistent with every other list screen
  • Changed Audit log detail rows are keyboard- and screen-reader-accessible
  • Fixed Accessibility: 530 WCAG violation nodes resolved to zero (contrast at root cause, accessible names on all controls, decorative icons hidden from assistive tech, 24px minimum targets)
  • Fixed Policy creation returns the standard API response envelope