+``` + +--- + +## 7. Enforcement Checklist + +### Color Token Rules +- [x] No `bg-white` / `bg-zinc-50` for surfaces — use `bg-surface` +- [x] No `text-zinc-50` / `text-zinc-100` for surfaces — use `text-ink` +- [x] No `bg-zinc-900` / `bg-zinc-950` for surfaces — use `bg-surface` or `bg-surface-card` +- [x] Raw zinc OK for: borders, disabled states, code, terminal surfaces + +### Accessibility Rules +- [x] All buttons have focus rings (verified in tests) +- [x] All modals use Radix Dialog (verified) +- [x] All tooltips use `role="tooltip"` + `aria-describedby` (verified) +- [x] No `outline-none` without focus ring (verified) +- [x] All inputs have visible labels (verified pattern) +- [x] Contrast ratios at 4.5:1 minimum (verified above) +- [x] `prefers-reduced-motion` suppresses all animations (verified in globals.css) +- [x] Context menu has keyboard navigation (verified in ContextMenu.keyboard.test.tsx) +- [x] Theme switching works: System/Light/Dark modes verified + +--- + +## 8. Canvas Architecture (Verified) + +**Stack:** +- `@xyflow/react` v12 (React Flow) — node/edge rendering +- Next.js 14 App Router +- Tailwind v4 with CSS custom properties +- Zustand for state management + +**Directory Structure:** +``` +canvas/src/ +├── components/ # Canvas.tsx, Toolbar.tsx, ContextMenu.tsx, SidePanel.tsx, WorkspaceNode.tsx, A2AEdge.tsx +├── stores/ # secrets-store.ts (only store) +├── hooks/ # useSocketEvent.ts, useTemplateDeploy.tsx, useWorkspaceName.ts +├── lib/ # api.ts, auth.ts, canvas-actions.ts, design-tokens.ts, theme.ts, theme-provider.tsx +└── app/ # Next.js App Router +``` + +## 9. Known Issues (Technical Debt) + +### Performance Issues +- **secrets-store.ts getGrouped() selector** — Creates new objects every call (Object.fromEntries + arrays) — not memoized. Causes performance issues with frequent re-renders. Needs selector optimization. + +### Code Quality +- Check for `any` types in canvas/ directory +- Verify pre-commit hook actually fails on 'use client' violations (unverified) +- Verify all Zustand selectors avoid object creation (see getGrouped issue above) +- Check 'use client' directive on hook-using components + +### Testing +- Add axe-core integration for automated accessibility testing +- Visual regression tests — no screenshot tests exist yet (KI-006) +- Target >80% test coverage on changed files + +## 10. Remaining Open Items + +### Accessibility Gaps +1. **Screen reader announcements** — Node/edge changes not announced. Need `aria-live="polite"` region. +2. **Keyboard shortcut help dialog** — No dedicated dialog. Shortcuts exist in `useKeyboardShortcuts.ts` but no `aria-describedby` hints on buttons. +3. **Edge anchor accessibility** — React Flow handles purely visual. Need ARIA annotations for screen readers. +4. **Drag-and-drop keyboard alternative** — Mouse only. Need keyboard equivalent for node rearrangement. + +### Performance +5. **secrets-store.ts getGrouped()** — Not memoized, creates new objects every call.