local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
Wails IPC raise endpoint, stale process cleanup
.autoflow/: full PRD / Design Spec / Architecture / Testing docs
(4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7.5 KiB
7.5 KiB
09 — 無障礙(A11y)要求
9.0 目標與範圍(第四輪 R4-3 定案)
目標:盡力而為(best effort),不以 WCAG 2.2 Level AA 為硬性驗收標準。
原本規劃以「WCAG 2.2 AA 合規」作為硬指標,但第四輪決策 R4-3 將其從硬目標降級為「盡力而為」,理由:
- 本產品為內部工具、工程師族群為主,非對外公眾服務,無法律合規壓力
- 硬性 AA 驗證(axe serious=0、screen reader 全流程、色彩對比全面實測)會佔用 M1 大量人力,排擠核心功能
- PRD 非功能需求已把 a11y 列入 non-goals(不做硬性驗證,只列為指引)
本章角色變更為「a11y 設計指引」:Design 在元件設計時參考本章原則,Frontend 在實作時盡量採納,但不以此作為 code review 或 QA 的 blocker。
仍會做的(low cost 的基本盤):
- 所有可聚焦元素有 visible focus ring(無額外成本)
- 語意化 HTML(
<button>、<nav>、<main>,不用純<div>) <label>與<input>正確關聯aria-label給 icon-only button- 鍵盤可完成核心流程(Tab 順序大致合理即可,不強求完美)
- 尊重
prefers-reduced-motion
不做的(高成本項目,R4-3 後明確排除):
- 色彩對比逐一實測(4.5:1、3:1)
- Screen reader 全流程人工驗證(VoiceOver / NVDA)
- axe / Lighthouse 自動掃描作為 CI gate(可跑但不 block)
- Reflow 320px 支援
- ARIA 角色完整覆蓋
- 推論結果的「非視覺呈現」文字清單(原 9.8)
以下各節作為指引保留,實作時採納即可;不列為驗收條件。
9.1 色彩對比
| 元素類型 | 最低對比 | 檢驗方式 |
|---|---|---|
| 正文 body text | 4.5 : 1 | Chrome DevTools contrast checker |
| 大字體(≥18pt 或 ≥14pt bold) | 3 : 1 | 同上 |
| UI 元件(border、icon) | 3 : 1 | 手動檢查 |
| Focus ring | 3 : 1(對周邊背景) | 手動檢查 |
已知需注意:
- Dark mode 的
color.muted-foreground(oklch 0.708) 對color.card背景需複測 - Mock badge 的黃底黑字需達 4.5 : 1
9.2 觸控/點擊目標
| 元素 | 最小尺寸 |
|---|---|
| Button / Icon button | 40×40px(桌面 app 可略小於 44,因為用滑鼠) |
| Sidebar item | 44×240px |
| Checkbox / Radio hit area | 32×32px(含 label 區域) |
桌面 app 例外:因為主要輸入裝置是滑鼠,可以比 mobile 44×44 稍小,但不能低於 32×32。
9.3 鍵盤導航
所有功能必須可用鍵盤完成,無 mouse 也能跑完整流程。
Tab 順序原則
- Header(幫助按鈕、Mock badge)
- Sidebar(主導航 1→4,然後 Settings)
- Content 主區塊(由上到下、由左到右)
- 頁面內的主 CTA 位置要 Tab-friendly
特殊鍵
| 鍵 | 行為 |
|---|---|
| Tab / Shift+Tab | 下一個 / 上一個可聚焦元素 |
| Enter | 啟動按鈕、提交表單 |
| Space | 啟動按鈕、切換 checkbox |
| Esc | 關閉 modal、drawer、tooltip、dropdown menu |
| 方向鍵 | 清單中移動(如 sidebar 項目、model grid) |
| ⌘/Ctrl + K | 保留給未來 command palette(目前不做) |
Focus Ring
- 所有可聚焦元素必須有可見 focus ring
- 使用
color.ring(oklch 0.708 / 0.556),2px outline + 2px offset - 不要用
outline: none而不補替代方案
Skip Link
在 Sidebar 最前面加 skip to main content link(預設 sr-only,Tab 聚焦時顯示)。
9.4 ARIA
Landmark roles
<aside role="navigation" aria-label="主導航"> <!-- Sidebar -->
<header role="banner"> <!-- Header -->
<main role="main" id="main-content"> <!-- Content -->
常用 ARIA 屬性
| 場景 | ARIA |
|---|---|
| Sidebar 當前頁 | aria-current="page" |
| Tab 群組 | role="tablist" / role="tab" / aria-selected / aria-controls |
| Modal 開啟時 | role="dialog" / aria-modal="true" / aria-labelledby |
| Loading 按鈕 | aria-busy="true" / aria-label="載入中" |
| 禁用按鈕 | aria-disabled="true"(不用 disabled 屬性以保留可聚焦性) |
| Toast | role="status"(success/info)/ role="alert"(error) |
| Dropdown | aria-haspopup="menu" / aria-expanded |
| Mock badge | role="status" / aria-label="目前為 Mock 模式" |
動態內容
Live regions 用 aria-live:
| 場景 | aria-live |
|---|---|
| Server 狀態變化 | polite |
| 推論結果更新 | off(太頻繁會吵) |
| 錯誤訊息 | assertive |
| Toast success | polite |
9.5 圖片與圖示
| 類型 | 標註 |
|---|---|
| 裝飾性圖示 | aria-hidden="true" |
| 功能性圖示(icon only button) | aria-label="動作描述" |
| 資訊性圖片(logo、插圖) | alt="..." |
| 影片 feed(攝影機串流) | aria-label="即時攝影機畫面"(無法提供動態描述) |
| 推論結果 overlay(bounding box) | 獨立顯示為清單,不只靠視覺(見 9.8) |
9.6 表單
- 所有 input 必須有對應的
<label> - 錯誤訊息用
aria-describedby連結 - 必填欄位用
aria-required="true"+ 視覺標記* - 驗證時機:
blur(失去焦點)+submit
9.7 Reduced Motion
偵測 prefers-reduced-motion: reduce:
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
不要直接禁用所有動畫 — 有些微小回饋(< 100ms)可以保留,只關閉長動畫與 parallax。
9.8 推論結果的非視覺呈現
攝影機串流 + bounding box 對視障使用者幾乎無意義。補償方案:
- Inference panel 同步顯示文字清單:「偵測到:人 (信心度 92%)、車 (信心度 85%)」
- 用
aria-live="polite"但節流(每 2 秒更新一次,否則太吵) - 提供「暫停語音播報」選項
9.9 語言與 lang 屬性
- HTML
lang屬性隨 i18n 動態切換:<html lang="zh-TW">或<html lang="en"> - 避免混雜未標註語言的文字(如中文頁面中的英文專有名詞用
<span lang="en">)
9.10 測試與驗證(R4-3 後:不列為硬指標)
本節原先定義 Lighthouse a11y ≥ 95、axe 無 critical/serious 的硬指標,第四輪 R4-3 後改為「建議但非必要」。
| 工具 | 建議用途(非強制) |
|---|---|
| axe DevTools | 開發時期手動自檢常見問題(不納入 CI gate) |
| Lighthouse | 偶爾看一下分數即可(不設最低門檻) |
| 鍵盤測試 | 主要流程用鍵盤跑過一次(核心流程能通即可) |
| Screen reader | 不做(R4-3 明確排除) |
| 色彩對比 | 不做逐項實測,依 Design Tokens 的 oklch 色盤視覺合理即可 |
驗收條件:無硬性 a11y 驗收條件。若 Frontend 實作時有餘力可追加,不強制。
9.11 與 i18n 的互動
中英雙語時注意:
- 英文版某些標籤可能比中文長(如「繼續」vs「Continue」),設計要容錯
- 確認 RTL 不是需求範圍(中英都是 LTR,確認後可放心)
9.12 可忽略範圍(需使用者確認)
以下 WCAG 標準因桌面 app 特性可以忽略,列出讓使用者確認:
- 1.4.10 Reflow(320px 寬度可用) — 桌面 app 最小視窗 960px,不支援 320px
- 2.4.5 Multiple Ways — 不提供全域搜尋、sitemap(IA 太淺不需要)
- 3.1.4 Abbreviations — 某些術語(KL720、FPS、.nef)不提供縮寫展開