v0.2.0: WCAG 2.2 AAA accessibility + toggle fix + version bump

This commit is contained in:
2026-02-18 19:15:19 +02:00
parent b8791ecc64
commit da066e382e
6 changed files with 63 additions and 25 deletions

View File

@@ -21,7 +21,7 @@
<img src="https://img.shields.io/badge/svelte-5-FF3E00?style=flat-square&logo=svelte&logoColor=white" alt="Svelte 5" /> <img src="https://img.shields.io/badge/svelte-5-FF3E00?style=flat-square&logo=svelte&logoColor=white" alt="Svelte 5" />
<img src="https://img.shields.io/badge/rust-2021-000000?style=flat-square&logo=rust&logoColor=white" alt="Rust" /> <img src="https://img.shields.io/badge/rust-2021-000000?style=flat-square&logo=rust&logoColor=white" alt="Rust" />
<img src="https://img.shields.io/badge/tailwind-v4-06B6D4?style=flat-square&logo=tailwindcss&logoColor=white" alt="Tailwind v4" /> <img src="https://img.shields.io/badge/tailwind-v4-06B6D4?style=flat-square&logo=tailwindcss&logoColor=white" alt="Tailwind v4" />
<img src="https://img.shields.io/badge/WCAG_2.1-AA-228B22?style=flat-square" alt="WCAG 2.1 AA" /> <img src="https://img.shields.io/badge/WCAG_2.2-AAA-228B22?style=flat-square&logo=w3c&logoColor=white" alt="WCAG 2.2 AAA" />
</p> </p>
<p align="center"> <p align="center">
@@ -320,19 +320,52 @@ Native Windows toast notifications for:
### ♿ Accessibility ### ♿ 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. <p>
<img src="https://img.shields.io/badge/WCAG_2.2-AAA_Conformance-228B22?style=for-the-badge&logo=w3c&logoColor=white" alt="WCAG 2.2 AAA Conformance" />
<img src="https://img.shields.io/badge/since-v0.2.0-blue?style=for-the-badge" alt="Since v0.2.0" />
</p>
| | Feature | Description | 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.
|:--|:--------|:------------|
| ⌨️ | **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. | > **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.
| 🔍 | **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. | #### Contrast & Visual Design
| 🎯 | **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. | | | Feature | Standard | Description |
| 🖥️ | **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. | | 🎨 | **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. |
| 🏷️ | **Descriptive labels** | All toggle switches, steppers, buttons, dropdowns, and form controls have descriptive accessible names | | 🔤 | **Large text contrast** | AAA 4.5:1 | Headings and large text (18px+) meet 4.5:1 minimum. Timer countdown, break titles validated. |
| 👆 | **Touch targets** | Interactive elements meet minimum 32x32px hit areas for comfortable interaction | | 🎯 | **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. |
<br /> <br />
@@ -723,7 +756,7 @@ No contribution agreements to sign. No corporate CLAs. No licensing traps. Every
- Report bugs or rough edges - Report bugs or rough edges
- Suggest new break activities (especially with physiotherapy or ergonomics knowledge) - 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 - Port idle detection to macOS/Linux
- Translate the interface - Translate the interface
- Share it with someone who needs it - Share it with someone who needs it

View File

@@ -1,7 +1,7 @@
{ {
"name": "core-cooldown", "name": "core-cooldown",
"private": true, "private": true,
"version": "0.1.3", "version": "0.2.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

2
src-tauri/Cargo.lock generated
View File

@@ -480,7 +480,7 @@ dependencies = [
[[package]] [[package]]
name = "core-cooldown" name = "core-cooldown"
version = "0.1.2" version = "0.2.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chrono", "chrono",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "core-cooldown" name = "core-cooldown"
version = "0.1.3" version = "0.2.0"
edition = "2021" edition = "2021"
[lib] [lib]

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json", "$schema": "https://raw.githubusercontent.com/tauri-apps/tauri/dev/crates/tauri-config-schema/schema.json",
"productName": "Core Cooldown", "productName": "Core Cooldown",
"version": "0.1.3", "version": "0.2.0",
"identifier": "com.corecooldown.app", "identifier": "com.corecooldown.app",
"build": { "build": {
"frontendDist": "../dist", "frontendDist": "../dist",

View File

@@ -15,19 +15,24 @@
} }
</script> </script>
<!-- 44px hit area wrapper (WCAG 2.5.8) with compact visual toggle inside -->
<button <button
type="button" type="button"
role="switch" role="switch"
aria-label={label} aria-label={label}
aria-checked={checked} aria-checked={checked}
class="relative inline-flex h-[28px] w-[52px] min-h-[44px] shrink-0 cursor-pointer rounded-full class="relative inline-flex min-h-[44px] min-w-[52px] shrink-0 cursor-pointer items-center justify-center
transition-colors duration-200 ease-in-out" bg-transparent border-none p-0"
style="background: {checked ? $config.accent_color : '#1a1a1a'};"
onclick={toggle} onclick={toggle}
> >
<span <span
class="pointer-events-none inline-block h-[22px] w-[22px] rounded-full class="inline-flex h-[28px] w-[52px] items-center rounded-full transition-colors duration-200 ease-in-out"
shadow-sm transition-transform duration-200 ease-in-out style="background: {checked ? $config.accent_color : '#1a1a1a'};"
{checked ? 'translate-x-[27px] bg-white' : 'translate-x-[3px] bg-[#666]'} mt-[3px]" >
></span> <span
class="pointer-events-none inline-block h-[22px] w-[22px] rounded-full
shadow-sm transition-transform duration-200 ease-in-out
{checked ? 'translate-x-[27px] bg-white' : 'translate-x-[3px] bg-[#666]'}"
></span>
</span>
</button> </button>