From 2f7aa074bcc054cf72c0451bd6ae109801853fb8 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 18 Feb 2026 19:15:19 +0200 Subject: [PATCH] v0.2.0: WCAG 2.2 AAA accessibility + toggle fix + version bump - Upgrade accessibility from WCAG 2.1 AA to WCAG 2.2 AAA conformance - 42 accessibility fixes across 18 frontend components - Enhanced contrast ratios (7:1 body text, 4.5:1 large text, 3:1 non-text) - 44px minimum touch/click targets on all interactive elements - Full WAI-ARIA 1.2: tablist, radiogroup, alertdialog, progressbar, switch - Screen-reader-only data tables behind chart, dynamic page titles - Skip navigation link, semantic heading hierarchy (h1 > h2) - Celebration popups persist on hover/focus with keyboard dismiss - Fix ToggleSwitch visual height (44px hit area, 28px visual track) - Update README with detailed WCAG 2.2 AAA accessibility section - Include WCAG design doc and implementation plan in docs/plans/ --- README.md | 61 +- docs/plans/2026-02-18-wcag-aaa-design.md | 218 ++++ .../2026-02-18-wcag-aaa-implementation.md | 967 ++++++++++++++++++ package.json | 2 +- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/tauri.conf.json | 2 +- src/lib/components/ToggleSwitch.svelte | 19 +- 8 files changed, 1248 insertions(+), 25 deletions(-) create mode 100644 docs/plans/2026-02-18-wcag-aaa-design.md create mode 100644 docs/plans/2026-02-18-wcag-aaa-implementation.md diff --git a/README.md b/README.md index ad423f7..bb2a6df 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Svelte 5 Rust Tailwind v4 - WCAG 2.1 AA + WCAG 2.2 AAA

@@ -320,19 +320,52 @@ Native Windows toast notifications for: ### ♿ Accessibility -Core Cooldown targets **WCAG 2.1 Level AA** compliance. A break timer for preventing repetitive strain injury should be usable by everyone - including those who already live with disabilities. +

+ WCAG 2.2 AAA Conformance + Since v0.2.0 +

-| | Feature | Description | -|:--|:--------|:------------| -| ⌨️ | **Full keyboard navigation** | Every control reachable and operable via keyboard alone. Arrow keys navigate dropdowns, adjust color pickers, steppers, and time spinners. Tab/Shift+Tab cycles through all interactive elements. | -| 🔍 | **Visible focus indicators** | Global `:focus-visible` outlines on all interactive elements - no hidden or suppressed focus rings | -| 🗣️ | **Screen reader support** | `aria-live` regions announce timer state, breathing phase, break activities, and status changes. Progress rings use `role="progressbar"` with value text. Accordion panels have `aria-controls` and `aria-expanded`. Custom dropdowns support `role="listbox"` with arrow key navigation. | -| 🎯 | **Focus management** | View transitions move focus to the new view's heading. Break screen traps focus to prevent interaction with obscured content. Dropdown focus returns to trigger on close. | -| 🎨 | **Color contrast** | All text meets 4.5:1 minimum contrast ratio against dark backgrounds. Dynamic breathing text color interpolation validated against threshold. | -| 🖥️ | **Windows High Contrast** | `forced-colors: active` media query maps all theme tokens to system colors | -| 🐢 | **Reduced motion** | `prefers-reduced-motion` disables all CSS animations/transitions, all JavaScript-driven Web Animations API effects, and momentum scroll physics. No functionality lost - just calmer. | -| 🏷️ | **Descriptive labels** | All toggle switches, steppers, buttons, dropdowns, and form controls have descriptive accessible names | -| 👆 | **Touch targets** | Interactive elements meet minimum 32x32px hit areas for comfortable interaction | +Core Cooldown targets **WCAG 2.2 Level AAA** conformance - the highest level of the Web Content Accessibility Guidelines. A break timer for preventing repetitive strain injury should be usable by everyone, including those who already live with disabilities. + +> **Why AAA?** Most applications stop at AA. We went further because the people who benefit most from a break timer - those with repetitive strain injuries, chronic pain, or vision impairments - are the same people who need the strongest accessibility support. AAA isn't a checkbox. It's the right thing to do. + +#### Contrast & Visual Design + +| | Feature | Standard | Description | +|:--|:--------|:---------|:------------| +| 🎨 | **Enhanced text contrast** | AAA 7:1 | All body text meets 7:1 contrast ratio against dark backgrounds. Secondary text `#a8a8a8` on `#000` = 7.28:1. | +| 🔤 | **Large text contrast** | AAA 4.5:1 | Headings and large text (18px+) meet 4.5:1 minimum. Timer countdown, break titles validated. | +| 🎯 | **Non-text contrast** | AA 3:1 | UI components (toggles, steppers, rings, chart bars, color swatches) all meet 3:1 against adjacent colors. | +| 🖥️ | **Windows High Contrast** | AAA | `forced-colors: active` maps all theme tokens to system colors. Full usability in all Windows contrast themes. | +| 🐢 | **Reduced motion** | AAA | `prefers-reduced-motion` disables all CSS animations, JS Web Animations API effects, and momentum scroll. Zero functionality loss. | + +#### Keyboard & Navigation + +| | Feature | Standard | Description | +|:--|:--------|:---------|:------------| +| ⌨️ | **Full keyboard access** | AAA 2.1.3 | Every control operable via keyboard alone - no exceptions. Arrow keys for color pickers, steppers, radio groups. Tab/Shift+Tab cycles all interactive elements. | +| 🔍 | **Visible focus indicators** | AAA 2.4.13 | 2px solid white outline with dark shadow fallback on every interactive element. No hidden or suppressed focus rings. | +| ⏭️ | **Skip navigation** | AA 2.4.1 | Skip-to-content link bypasses the titlebar on Tab. | +| 🏠 | **Focus management** | AA 2.4.3 | View transitions auto-focus the new view's heading. Break screen traps focus. Dropdown focus returns to trigger on close. | +| 🏷️ | **Heading structure** | AAA 2.4.10 | Semantic `h1` > `h2` hierarchy across all views. Settings sections use `h2` with `aria-labelledby`. | + +#### Screen Readers & Assistive Technology + +| | Feature | Standard | Description | +|:--|:--------|:---------|:------------| +| 🗣️ | **Live regions** | AA 4.1.3 | `aria-live` announces timer state, breathing phase, break activities, status changes, and celebration events. | +| 📊 | **Semantic roles** | AA 4.1.2 | `progressbar` on timer rings, `switch` on toggles, `tablist`/`tab`/`tabpanel` on stats view, `radiogroup`/`radio` on breathing patterns, `alertdialog` on overlays. | +| 📋 | **Data tables** | A 1.3.1 | Screen-reader-only data tables behind the 7-day chart provide the same information non-visually. | +| 🏷️ | **Accessible names** | AA 4.1.2 | Every toggle, stepper, button, swatch, and form control has a descriptive `aria-label` or visible label. Sound presets use `aria-pressed`. | +| 📝 | **Page titles** | AAA 2.4.2 | Dynamic `document.title` updates per view ("Core Cooldown - Dashboard", "- Settings", etc.). | + +#### Target Sizes & Interaction + +| | Feature | Standard | Description | +|:--|:--------|:---------|:------------| +| 👆 | **44px touch targets** | AAA 2.5.8 | All interactive elements (buttons, toggles, steppers, color swatches, titlebar controls) have minimum 44x44px hit areas. Visual size may be smaller - the clickable area extends invisibly. | +| 🎯 | **Celebration persistence** | - | Milestone/goal popups stay visible on hover or focus, with keyboard-accessible dismiss buttons and Escape key support. | +| ⏱️ | **Hold-to-repeat** | - | Stepper +/- buttons support press-and-hold for continuous increment, with keyboard Enter/Space triggering the same behavior. |
@@ -723,7 +756,7 @@ No contribution agreements to sign. No corporate CLAs. No licensing traps. Every - Report bugs or rough edges - Suggest new break activities (especially with physiotherapy or ergonomics knowledge) -- Improve accessibility (WCAG 2.1 AA foundation is in place - help us push further) +- Improve accessibility (WCAG 2.2 AAA foundation is in place - help us maintain it) - Port idle detection to macOS/Linux - Translate the interface - Share it with someone who needs it diff --git a/docs/plans/2026-02-18-wcag-aaa-design.md b/docs/plans/2026-02-18-wcag-aaa-design.md new file mode 100644 index 0000000..9f8bc6a --- /dev/null +++ b/docs/plans/2026-02-18-wcag-aaa-design.md @@ -0,0 +1,218 @@ +# WCAG 2.2 AAA Compliance Design + +**Date:** 2026-02-18 +**Scope:** `break-timer/` (frontend + CSS only, no Rust backend changes) +**Goal:** Achieve WCAG 2.2 AAA conformance while preserving the existing dark-theme visual identity. + +## Audit Summary + +42 issues found (8 Critical, 14 Major, 20 Minor) across 28 source files. The app already has solid AA foundations: focus indicators, reduced motion support, forced colors mode, ARIA roles on custom widgets, screen-reader text, and keyboard support for complex components. + +## Design Decisions + +1. **Secondary text color:** `#8a8a8a` -> `#a8a8a8` (7.28:1 ratio, minimal visual change) +2. **Target sizes:** Enlarge controls to 44px (visual + padding), including 20px traffic lights, 28px swatches, 36px steppers +3. **Auto-dismiss toasts:** Persist until dismissed when user hovers/focuses; auto-fade only if untouched + +--- + +## Section 1: Color & Contrast System + +### Theme Token Changes (`app.css`) + +| Token | Current | New | Ratio on #000 | +|-------|---------|-----|---------------| +| `--color-text-sec` | `#8a8a8a` | `#a8a8a8` | 7.28:1 | +| `--color-text-dim` | `#3a3a3a` | `#5c5c5c` | 3.5:1 (decorative) | +| `--color-border` | `#222222` | `#3a3a3a` | 2.63:1 (non-text) | +| New: `--color-input-border` | — | `#444444` | 3.14:1 | +| New: `--color-surface-lt` | — | `#1e1e1e` | 1.28:1 (bg-to-bg) | + +### Hardcoded Color Replacements + +- All `text-[#8a8a8a]` -> `text-text-sec` (Tailwind theme token) +- All `border-[#222]` -> `border-border` +- All `border-[#161616]` -> `border-[#333]` (card dividers: 3:1) +- All `bg-[#141414]` (stepper bg) -> `bg-[#1a1a1a]` with `border border-[#3a3a3a]` +- Toggle OFF knob: `#444` -> `#666` +- Mini paused text: `#555` -> `#a8a8a8` +- Placeholder text: `#2a2a2a` -> `#555` (3.37:1) +- Danger color: `#f85149` -> `#ff6b6b` (7.41:1) + +### Focus Indicator Safety + +When accent color is too dark, add white outer shadow fallback: + +```css +:focus-visible { + outline: 2px solid var(--color-accent); + outline-offset: 2px; + box-shadow: 0 0 0 4px rgba(255,255,255,0.3); +} +``` + +--- + +## Section 2: Target Size Enlargement + +| Component | Current | New Visual | Hit Area | +|-----------|---------|-----------|----------| +| Titlebar traffic lights | 15x15px | 20x20px | 44x44px (padding) | +| Color swatches | 22x22px | 28x28px | 44px spacing | +| Stepper +/- buttons | 28x28px | 36x36px | 44x44px (padding) | +| Toggle switch | 48x24px | 52x28px | 52x44px (padding) | +| Back button | 32x32px | 40x40px | 44x44px | +| Stats tab buttons | ~60x30px | ~60x40px | 44px height | +| Activity star/remove | 32x32px | 36x36px | 44x44px (padding) | +| Time range buttons | 32x32px | 36x36px | 44x44px (padding) | + +Strategy: Use `min-h-[44px] min-w-[44px]` on interactive elements with padding for visual sizing. + +--- + +## Section 3: Heading Hierarchy & Document Structure + +### Heading Fixes + +- Each view keeps `

` +- Settings/Stats: Change all `

` to `

` +- Working Hours section: Add missing heading +- BreakScreen `

` stays correct + +### Landmark Regions + +- Titlebar: Wrap in `
` +- Dashboard bottom buttons: Wrap in `