- 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/
798 lines
34 KiB
Markdown
798 lines
34 KiB
Markdown
<p align="center">
|
|
<picture>
|
|
<source media="(prefers-color-scheme: dark)" srcset="https://img.shields.io/badge/%F0%9F%A7%8A-_-0d1117?style=for-the-badge&labelColor=0d1117" />
|
|
<img src="https://img.shields.io/badge/%F0%9F%A7%8A-_-white?style=for-the-badge&labelColor=white" alt="" />
|
|
</picture>
|
|
</p>
|
|
|
|
<h1 align="center">
|
|
<strong>CORE COOLDOWN</strong>
|
|
</h1>
|
|
|
|
<p align="center">
|
|
<em>A portable break timer for Windows that reminds you to rest.</em><br />
|
|
<em>Because your time and your body belong to you - not to your screen.</em>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<a href="https://creativecommons.org/publicdomain/zero/1.0/"><img src="https://img.shields.io/badge/license-CC0_1.0-blue?style=flat-square" alt="CC0 1.0" /></a>
|
|
<img src="https://img.shields.io/badge/platform-Windows-0078D6?style=flat-square&logo=windows&logoColor=white" alt="Windows" />
|
|
<img src="https://img.shields.io/badge/tauri-v2-24C8D8?style=flat-square&logo=tauri&logoColor=white" alt="Tauri v2" />
|
|
<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/tailwind-v4-06B6D4?style=flat-square&logo=tailwindcss&logoColor=white" alt="Tailwind v4" />
|
|
<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 align="center">
|
|
<a href="https://git.lashman.live/lashman/core-cooldown/releases"><strong>Download latest release</strong></a>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 💡 Why does this exist?
|
|
|
|
Repetitive strain injury and eye strain are not personal failings. They are the predictable result of systems that treat human attention as an extractable resource. Every person at a screen deserves a tool that gently interrupts the grind - one that serves *them*, not a subscription model, not an analytics dashboard, not a corporate wellness KPI.
|
|
|
|
Core Cooldown is a single portable `.exe`. No installer, no account, no telemetry, no data leaving your machine. Drop it in a folder and run it. It reminds you to rest. That's it.
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 🧭 Philosophy
|
|
|
|
Core Cooldown exists because rest is not a luxury. It is a fundamental need that no productivity framework, no employer, and no software platform should gatekeep behind a paywall or a subscription.
|
|
|
|
This application:
|
|
|
|
- **Collects nothing.** No analytics, no telemetry, no usage tracking, no crash reports phoned home. Your break habits are your own business.
|
|
- **Costs nothing.** Not "free tier with limitations." Not "free for personal use." Free, unconditionally, for everyone.
|
|
- **Requires nothing.** No account, no email, no app store, no internet connection after download. It runs on your machine and answers to you alone.
|
|
- **Owns nothing.** Released under CC0 - the most complete relinquishment of rights possible under law. There is no owner. There are no restrictions. The code belongs to the commons.
|
|
|
|
Tools for human wellbeing should never be enclosed, never be scarce, and never serve a master other than the person using them.
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 📸 Screenshots
|
|
|
|
<p align="center">
|
|
<img src="screenshots/01-dashboard.png" alt="Dashboard - Main Timer" width="420" /><br />
|
|
<sub><strong>Dashboard</strong> - Focus timer with countdown ring, status pill, pomodoro dots, and quick controls</sub>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
<p align="center">
|
|
<img src="screenshots/02-stats.png" alt="Statistics" width="420" /><br />
|
|
<sub><strong>Statistics</strong> - Daily summary, compliance rate, streaks, and 7-day history chart</sub>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
<p align="center">
|
|
<img src="screenshots/03-settings.png" alt="Settings" width="420" /><br />
|
|
<sub><strong>Settings</strong> - 18 grouped configuration cards with live preview</sub>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
<p align="center">
|
|
<img src="screenshots/04-break.png" alt="Break Screen" width="600" /><br />
|
|
<sub><strong>Break Screen</strong> - Always-on-top break overlay with breathing guide and activity suggestions</sub>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
<p align="center">
|
|
<img src="screenshots/05-mini.png" alt="Mini Mode" width="300" /><br />
|
|
<sub><strong>Mini Mode</strong> - Compact floating timer, click-through until hovered</sub>
|
|
</p>
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## ✨ Features
|
|
|
|
### ⏱️ Timer & Breaks
|
|
|
|
| | Feature | Description |
|
|
|:--|:--------|:------------|
|
|
| 🔄 | **Configurable intervals** | Work sessions from 5-120 min, breaks from 1-60 min |
|
|
| 🔔 | **Pre-break warnings** | Toast notification + optional sound alert before each break |
|
|
| 🛡️ | **Break enforcement** | Always-on-top break window with optional fullscreen mode |
|
|
| 🖥️ | **Multi-monitor** | Fullscreen break overlay spans all connected monitors |
|
|
| 🔒 | **Strict mode** | Removes skip and cancel buttons entirely |
|
|
| ⏩ | **Early end** | Optionally allow ending a break after 50% completion |
|
|
| 😴 | **Snooze** | Delay breaks by a configurable duration (with limits) |
|
|
| ⚡ | **Immediate breaks** | Skip pre-break notification, go straight into break |
|
|
| 🎯 | **Manual break** | Start a break anytime from the dashboard or tray menu |
|
|
|
|
<br />
|
|
|
|
### 🍅 Pomodoro Mode
|
|
|
|
A full Pomodoro timer built in. Alternates short breaks with a longer recovery break after a configurable number of focus sessions.
|
|
|
|
- **Short breaks before long** - 1-10 short breaks then one long break (default: 3 + 1)
|
|
- **Long break duration** - independently configurable (5-60 min, default: 15 min)
|
|
- **Custom titles and messages** - personalize the long break screen
|
|
- **Cycle indicator** - dashboard shows dot progress through the current cycle
|
|
- **Reset on skip** - optionally restart the cycle when skipping a break
|
|
|
|
<br />
|
|
|
|
### 👁️ Microbreaks (20-20-20 Rule)
|
|
|
|
Quick eye rest reminders between full breaks. The 20-20-20 rule: every 20 minutes, look at something 20 feet away for 20 seconds.
|
|
|
|
- **Independent timer** - runs alongside the main break timer
|
|
- **Configurable frequency** - 5-60 minutes (default: 20)
|
|
- **Configurable duration** - 10-60 seconds (default: 20)
|
|
- **Subtle overlay** - non-blocking overlay with activity suggestion
|
|
- **Sound notification** - optional audio cue
|
|
- **Pauses during breaks** - no microbreak interruptions during main breaks
|
|
|
|
<br />
|
|
|
|
### 🌬️ Breathing Guide
|
|
|
|
A visual breathing exercise during breaks. The breathing text pulses with the rhythm - scaling up on inhale, holding on hold, scaling down on exhale - with a color gradient that interpolates between your accent and break colors.
|
|
|
|
| Pattern | Timing |
|
|
|:--------|:-------|
|
|
| **Box** | 4s in · 4s hold · 4s out · 4s hold |
|
|
| **Relaxing** | 4s in · 7s hold · 8s out |
|
|
| **Energizing** | 6s in · 2s hold · 6s out · 2s hold |
|
|
| **Calm** | 4s in · 4s hold · 6s out |
|
|
| **Deep** | 5s in · 5s out |
|
|
|
|
<br />
|
|
|
|
### 💤 Idle Detection & Smart Breaks
|
|
|
|
| | Feature | Description |
|
|
|:--|:--------|:------------|
|
|
| 💤 | **Idle auto-pause** | Detects inactivity via Windows API and pauses the timer |
|
|
| ▶️ | **Auto-resume** | Timer resumes automatically when you return |
|
|
| 🌿 | **Smart breaks** | Recognizes natural breaks (stepping away) and optionally counts them toward your daily goal |
|
|
| ⚙️ | **Configurable thresholds** | Idle timeout (30-600s) and smart break threshold (2-15 min) are independently adjustable |
|
|
|
|
<br />
|
|
|
|
### 🎬 Presentation Mode
|
|
|
|
Detects fullscreen applications (presentations, video calls, games) and defers breaks until you exit.
|
|
|
|
- **Auto-detection** - monitors for fullscreen windows
|
|
- **Microbreak deferral** - optionally defer microbreaks too
|
|
- **Toast notification** - alerts you when a break is deferred
|
|
- **Queued breaks** - deferred breaks trigger when the fullscreen app closes
|
|
|
|
<br />
|
|
|
|
### 🤸 Break Activities
|
|
|
|
Each break shows a randomized suggestion from a curated library of **71 activities** across four categories:
|
|
|
|
| Category | Examples |
|
|
|:---------|:---------|
|
|
| 👁️ **Eyes** | Palming, distance focusing, figure-eights, warm compress visualization, peripheral awareness |
|
|
| 🤸 **Stretch** | Neck rolls, wrist flexion, shoulder blade squeezes, chest openers, spinal twists, hip flexors |
|
|
| 🌬️ **Breathing** | Box breathing, 4-7-8 technique, alternate nostril, diaphragmatic, resonance breathing |
|
|
| 🏃 **Movement** | Calf raises, wall push-ups, balance exercises, gentle squats, toe touches, desk yoga |
|
|
|
|
Activities cycle every 30 seconds and never repeat consecutively.
|
|
|
|
**Activity Manager** - customize your break experience from settings:
|
|
- **Custom activities** - add your own with category assignment
|
|
- **Favorites** - star activities to increase their appearance frequency (3x weight)
|
|
- **Enable/disable** - toggle any built-in or custom activity
|
|
- **Momentum scroll** - iOS-style drag scrolling with elastic overscroll in the activity list
|
|
|
|
<br />
|
|
|
|
### 🏆 Goals & Streaks
|
|
|
|
| | Feature | Description |
|
|
|:--|:--------|:------------|
|
|
| 🎯 | **Daily goal** | Set a target number of breaks per day (1-30, shown on dashboard) |
|
|
| 🎉 | **Celebrations** | Confetti animation on milestones and goal completion |
|
|
| 🔥 | **Streak tracking** | Current and best consecutive-day streaks |
|
|
| 🔔 | **Streak notifications** | Toast notification on streak milestones |
|
|
|
|
<br />
|
|
|
|
### 🌑 Screen Dimming
|
|
|
|
A gentle pre-break nudge that gradually dims your screen before the break starts.
|
|
|
|
- **Configurable timing** - start dimming 3-60 seconds before break
|
|
- **Adjustable intensity** - maximum opacity from 10% to 70%
|
|
- **Smooth transition** - gradual linear fade, not a sudden jump
|
|
|
|
<br />
|
|
|
|
### 📅 Working Hours Schedule
|
|
|
|
A per-day schedule with multiple time ranges per day. The timer only runs during your configured hours - outside those hours, it pauses automatically.
|
|
|
|
- **Monday through Sunday** - each day independently togglable
|
|
- **Multiple ranges per day** - for split shifts or non-contiguous work blocks
|
|
- **Weekend defaults** - Saturday and Sunday disabled by default
|
|
|
|
<br />
|
|
|
|
### 📊 Statistics & History
|
|
|
|
| | Metric | Description |
|
|
|:--|:-------|:------------|
|
|
| ✅ | **Today's summary** | Breaks completed, skipped, snoozed, and total break time |
|
|
| 🌿 | **Natural breaks** | Separately tracked idle breaks (with optional stat inclusion) |
|
|
| 📈 | **Compliance rate** | Ratio of completed to total scheduled breaks |
|
|
| 🔥 | **Streak tracking** | Current and best consecutive-day streaks |
|
|
| 📉 | **7-day chart** | Canvas-rendered bar chart showing daily break history |
|
|
|
|
All statistics stored locally in a plain JSON file next to the executable.
|
|
|
|
<br />
|
|
|
|
### 🔊 Sound Effects
|
|
|
|
Synthesized notification sounds via Web Audio API - no bundled audio files, no network requests.
|
|
|
|
> **8 presets:** Bell · Chime · Soft · Digital · Harp · Bowl · Rain · Whistle
|
|
|
|
Sounds play on break start, pre-break warning, and break completion. Volume configurable 0-100%.
|
|
|
|
<br />
|
|
|
|
### ⌨️ Global Keyboard Shortcuts
|
|
|
|
| Shortcut | Action |
|
|
|:---------|:-------|
|
|
| `Ctrl + Shift + P` | Pause / resume timer |
|
|
| `Ctrl + Shift + B` | Start break now |
|
|
| `Ctrl + Shift + S` | Show / hide main window |
|
|
|
|
Works system-wide, even when Core Cooldown is not focused.
|
|
|
|
<br />
|
|
|
|
### 🔵 System Tray
|
|
|
|
- **Dynamic icon** - 32x32 progress arc rendered in real-time (orange = focus, purple = break, dimmed = paused)
|
|
- **Countdown tooltip** - hover over tray icon to see time remaining
|
|
- **Context menu** - pause/resume, start break, toggle mini mode, show/hide, quit
|
|
|
|
<br />
|
|
|
|
### 📌 Mini Mode
|
|
|
|
A compact floating timer (200x50px) that sits on top of your other windows.
|
|
|
|
- **Click-through** - completely transparent to mouse events, never blocks what's underneath
|
|
- **Hover to grab** - hover for a configurable number of seconds and it becomes draggable
|
|
- **Double-click** - opens the main window
|
|
- **Togglable** - enable/disable from the tray menu
|
|
|
|
<br />
|
|
|
|
### 🎨 Appearance & Customization
|
|
|
|
| Setting | Range |
|
|
|:--------|:------|
|
|
| **UI zoom** | 50-200% with live preview |
|
|
| **Accent color** | Full color picker (SL pad + hue bar) for the main UI accent |
|
|
| **Break color** | Separate color for the break screen ring and breathing guide |
|
|
| **Countdown font** | Google Fonts selector for timer display |
|
|
| **Background blobs** | Animated gradient blobs with film grain overlay |
|
|
| **Break title & message** | Fully customizable text shown during breaks |
|
|
|
|
<br />
|
|
|
|
### 🔔 Notifications
|
|
|
|
Native Windows toast notifications for:
|
|
- Pre-break warnings (configurable seconds before break)
|
|
- Break completion
|
|
- Streak milestones
|
|
- Daily goal achievement
|
|
- Break deferral (presentation mode)
|
|
|
|
<br />
|
|
|
|
### 🪟 Window Behavior
|
|
|
|
- **Frameless window** with custom titlebar and drag region
|
|
- **Transparent background** with frosted glass effects (backdrop-blur)
|
|
- **Window position persistence** - main and mini windows remember position between launches
|
|
- **Animated view transitions** - directional fly/scale/fade transitions (700ms, cubicOut easing)
|
|
- **Momentum scroll** - iOS-style drag scrolling with elastic overscroll in settings
|
|
|
|
<br />
|
|
|
|
### ♿ Accessibility
|
|
|
|
<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>
|
|
|
|
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. |
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 📦 Portability
|
|
|
|
Core Cooldown is **fully portable**. The executable carries everything it needs and stores everything it creates right next to itself:
|
|
|
|
```
|
|
anywhere-you-want/
|
|
├── core-cooldown.exe <- the application
|
|
├── config.json <- your settings (auto-created on first run)
|
|
├── stats.json <- your break history (auto-created on first run)
|
|
└── data/ <- WebView2 runtime data (auto-created on first run)
|
|
```
|
|
|
|
- No installer
|
|
- No registry entries
|
|
- No writes to `%APPDATA%`, `%LOCALAPPDATA%`, or any system directory
|
|
- Move the folder anywhere - USB stick, shared drive, different machine
|
|
- Nothing to uninstall - delete the folder and it's gone, zero traces
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 🚀 Installation
|
|
|
|
```
|
|
1. Download core-cooldown.exe from the Releases page
|
|
2. Put it in any folder you like
|
|
3. Run it
|
|
```
|
|
|
|
That's it. No elevated permissions. No runtime dependencies. The first launch may take a moment while Windows initializes the WebView2 runtime.
|
|
|
|
**[Download latest release](https://git.lashman.live/lashman/core-cooldown/releases)**
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 🔧 Building from Source
|
|
|
|
<details>
|
|
<summary><strong>Prerequisites</strong></summary>
|
|
|
|
<br />
|
|
|
|
- **Node.js** (v18+) and **npm**
|
|
- **Rust** toolchain (`rustup`) with the `x86_64-pc-windows-gnu` target
|
|
- **MinGW-w64** - the GNU toolchain for Windows (provides linker, windres, dlltool)
|
|
|
|
</details>
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
git clone https://git.lashman.live/lashman/core-cooldown.git
|
|
cd core-cooldown
|
|
npm install
|
|
```
|
|
|
|
### Linker Configuration
|
|
|
|
Create or edit `src-tauri/.cargo/config.toml` to point to your MinGW installation:
|
|
|
|
```toml
|
|
[build]
|
|
target = "x86_64-pc-windows-gnu"
|
|
|
|
[target.x86_64-pc-windows-gnu]
|
|
linker = "C:/path/to/mingw64/bin/gcc.exe"
|
|
ar = "C:/path/to/mingw64/bin/ar.exe"
|
|
```
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Launch with hot-reload
|
|
npm run tauri dev
|
|
|
|
# Rust check (no full build)
|
|
cd src-tauri && cargo check
|
|
|
|
# Frontend only (no Tauri shell)
|
|
npm run dev
|
|
```
|
|
|
|
### Release Build
|
|
|
|
```bash
|
|
npm run tauri build
|
|
```
|
|
|
|
Output: `src-tauri/target/x86_64-pc-windows-gnu/release/core-cooldown.exe`
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 🏗️ Architecture
|
|
|
|
A split-architecture desktop app: Rust backend for system integration and timer logic, Svelte frontend rendered in a native WebView.
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ System Tray │
|
|
│ (dynamic icon · tooltip · menu) │
|
|
├──────────────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
|
│ │ Main Window │ │ Break Window│ │ Mini Window │ │
|
|
│ │ (WebView) │ │ (WebView) │ │ (WebView) │ │
|
|
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
|
|
│ │ │ │ │
|
|
│ └─────────┬────────┴──────────────────┘ │
|
|
│ │ Tauri IPC │
|
|
│ ┌─────────┴─────────┐ │
|
|
│ │ Rust Backend │ │
|
|
│ │ │ │
|
|
│ │ TimerManager │ state machine (1 tick/sec) │
|
|
│ │ Config │ JSON persistence (portable) │
|
|
│ │ Stats │ break history tracking │
|
|
│ │ IdleDetector │ GetLastInputInfo polling │
|
|
│ │ GlobalShortcuts │ Ctrl+Shift+P/B/S │
|
|
│ │ TrayIcon │ RGBA ring rendering │
|
|
│ │ Notifications │ Windows toast │
|
|
│ └───────────────────┘ │
|
|
│ │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
<details>
|
|
<summary><strong>Backend modules (Rust)</strong></summary>
|
|
|
|
| Module | Responsibility |
|
|
|:-------|:---------------|
|
|
| `lib.rs` | Tauri app builder, command registration, tray setup, timer tick thread, window management, global shortcuts, screen dim events, microbreak events, presentation mode detection |
|
|
| `config.rs` | Config struct (75 fields) with serde serialization, validation (clamping all values to safe ranges), portable file I/O |
|
|
| `timer.rs` | Timer state machine (`Running` / `Paused` / `BreakActive`), idle detection via Windows API, working hours enforcement, pomodoro cycle tracking, microbreak scheduling, presentation mode deferral |
|
|
| `stats.rs` | Daily break statistics, streak calculation, daily goal tracking, history queries, weekly summaries |
|
|
| `main.rs` | Entry point, WebView2 Runtime detection |
|
|
| `msvc_compat.rs` | MSVC CRT compatibility stubs for static WebView2Loader linking on MinGW |
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>Frontend layers (Svelte 5 + TypeScript)</strong></summary>
|
|
|
|
| Layer | Files |
|
|
|:------|:------|
|
|
| **Views** | `Dashboard`, `BreakScreen`, `Settings`, `StatsView` |
|
|
| **Windows** | `BreakWindow` (standalone break modal), `MiniTimer` (floating mini mode) |
|
|
| **Overlays** | `BreakOverlay` (break enforcement), `MicrobreakOverlay` (eye break), `DimOverlay` (screen dimming), `Celebration` (confetti) |
|
|
| **Components** | `TimerRing`, `Titlebar`, `ToggleSwitch`, `Stepper`, `ColorPicker`, `FontSelector`, `TimeSpinner`, `BackgroundBlobs`, `BreathingGuide`, `ActivityManager` |
|
|
| **Stores** | `timer.ts` (reactive timer state from IPC events), `config.ts` (config with debounced auto-save) |
|
|
| **Utilities** | `sounds.ts` (Web Audio synthesis), `activities.ts` (71 break activities), `animate.ts` (motion library: fadeIn, scaleIn, inView, pressable, glowHover, dragScroll) |
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>IPC contract</strong></summary>
|
|
|
|
**Commands** (frontend -> backend):
|
|
`get_config` · `save_config` · `update_pending_config` · `reset_config` · `toggle_timer` · `start_break_now` · `cancel_break` · `snooze` · `get_timer_state` · `set_view` · `get_stats` · `get_daily_history` · `get_weekly_summary` · `set_auto_start` · `get_auto_start_status` · `get_cursor_position` · `save_window_position`
|
|
|
|
**Events** (backend -> frontend):
|
|
`timer-tick` · `break-started` · `break-ended` · `prebreak-warning` · `config-changed` · `natural-break-detected` · `screen-dim-update` · `microbreak-started` · `microbreak-ended` · `milestone-reached` · `daily-goal-met` · `break-deferred`
|
|
|
|
</details>
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## ⚙️ Configuration Reference
|
|
|
|
All settings stored in `config.json` next to the executable. The settings panel exposes every option with live validation, but the file is plain JSON and can be edited by hand.
|
|
|
|
<details>
|
|
<summary><strong>Full configuration schema (71 keys)</strong></summary>
|
|
|
|
<br />
|
|
|
|
**Timer**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `break_duration` | `u32` | `5` | Duration of each break (1-60 min) |
|
|
| `break_frequency` | `u32` | `25` | Interval between breaks (5-120 min) |
|
|
| `auto_start` | `bool` | `true` | Start timer on launch |
|
|
|
|
**Pomodoro**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `pomodoro_enabled` | `bool` | `false` | Enable Pomodoro mode |
|
|
| `pomodoro_short_breaks` | `u32` | `3` | Short breaks before long (1-10) |
|
|
| `pomodoro_long_break_duration` | `u32` | `15` | Long break duration (5-60 min) |
|
|
| `pomodoro_long_break_title` | `string` | `"Long break"` | Long break title |
|
|
| `pomodoro_long_break_message` | `string` | `"Great work!..."` | Long break message |
|
|
| `pomodoro_reset_on_skip` | `bool` | `false` | Reset cycle when skipping |
|
|
|
|
**Microbreaks**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `microbreak_enabled` | `bool` | `false` | Enable 20-20-20 eye breaks |
|
|
| `microbreak_frequency` | `u32` | `20` | Microbreak interval (5-60 min) |
|
|
| `microbreak_duration` | `u32` | `20` | Microbreak duration (10-60 sec) |
|
|
| `microbreak_sound_enabled` | `bool` | `true` | Play sound on microbreak |
|
|
| `microbreak_show_activity` | `bool` | `true` | Show activity during microbreak |
|
|
| `microbreak_pause_during_break` | `bool` | `true` | No microbreaks during main breaks |
|
|
|
|
**Break Screen**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `break_title` | `string` | `"Rest your eyes"` | Title shown on break screen |
|
|
| `break_message` | `string` | `"Look away..."` | Message shown during breaks |
|
|
| `fullscreen_mode` | `bool` | `true` | Use fullscreen break window |
|
|
| `multi_monitor_break` | `bool` | `true` | Show overlay on all monitors |
|
|
| `show_break_activities` | `bool` | `true` | Show activity suggestions |
|
|
|
|
**Activities**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `custom_activities` | `array` | `[]` | User-created activities |
|
|
| `disabled_builtin_activities` | `array` | `[]` | Disabled built-in activities |
|
|
| `favorite_builtin_activities` | `array` | `[]` | Favorited built-in activities |
|
|
| `favorite_weight` | `u32` | `3` | How much more often favorites appear |
|
|
|
|
**Breathing Guide**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `breathing_guide_enabled` | `bool` | `true` | Show breathing guide during breaks |
|
|
| `breathing_pattern` | `string` | `"box"` | Breathing pattern (box/relaxing/energizing/calm/deep) |
|
|
|
|
**Behavior**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `strict_mode` | `bool` | `false` | Remove skip/cancel buttons |
|
|
| `allow_end_early` | `bool` | `true` | Allow ending break after 50% |
|
|
| `immediately_start_breaks` | `bool` | `false` | Skip pre-break notification |
|
|
| `snooze_duration` | `u32` | `5` | Snooze delay (1-30 min) |
|
|
| `snooze_limit` | `u32` | `3` | Max snoozes per cycle (0-5) |
|
|
|
|
**Alerts**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `notification_enabled` | `bool` | `true` | Enable toast notifications |
|
|
| `notification_before_break` | `u32` | `30` | Pre-break warning (0-300 sec) |
|
|
| `screen_dim_enabled` | `bool` | `false` | Gradually dim screen before breaks |
|
|
| `screen_dim_seconds` | `u32` | `10` | Start dimming N seconds before break |
|
|
| `screen_dim_max_opacity` | `f32` | `0.3` | Maximum dim intensity (10-70%) |
|
|
|
|
**Sound**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `sound_enabled` | `bool` | `true` | Play notification sounds |
|
|
| `sound_volume` | `u32` | `70` | Volume (0-100%) |
|
|
| `sound_preset` | `string` | `"bell"` | Sound preset |
|
|
|
|
**Idle & Smart Breaks**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `idle_detection_enabled` | `bool` | `true` | Enable idle auto-pause |
|
|
| `idle_timeout` | `u32` | `120` | Idle threshold (30-600 sec) |
|
|
| `smart_breaks_enabled` | `bool` | `true` | Detect natural breaks |
|
|
| `smart_break_threshold` | `u32` | `300` | Natural break threshold (120-900 sec) |
|
|
| `smart_break_count_stats` | `bool` | `false` | Count natural breaks in stats |
|
|
|
|
**Presentation Mode**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `presentation_mode_enabled` | `bool` | `true` | Defer breaks during fullscreen apps |
|
|
| `presentation_mode_defer_microbreaks` | `bool` | `true` | Also defer microbreaks |
|
|
| `presentation_mode_notification` | `bool` | `true` | Show toast when break deferred |
|
|
|
|
**Goals & Streaks**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `daily_goal_enabled` | `bool` | `true` | Track daily break target |
|
|
| `daily_goal_breaks` | `u32` | `8` | Target breaks per day (1-30) |
|
|
| `milestone_celebrations` | `bool` | `true` | Confetti on milestones |
|
|
| `streak_notifications` | `bool` | `true` | Toast on streak milestones |
|
|
|
|
**Appearance**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `ui_zoom` | `u32` | `100` | Interface zoom (50-200%) |
|
|
| `accent_color` | `string` | `"#ff4d00"` | Main accent color |
|
|
| `break_color` | `string` | `"#7c6aef"` | Break screen ring color |
|
|
| `countdown_font` | `string` | `""` | Google Font for countdown |
|
|
| `background_blobs_enabled` | `bool` | `false` | Animated background blobs |
|
|
|
|
**Working Hours**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `working_hours_enabled` | `bool` | `false` | Restrict timer to schedule |
|
|
| `working_hours_schedule` | `array` | Mon-Fri 09-18 | Per-day time ranges |
|
|
|
|
**Mini Mode**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `mini_click_through` | `bool` | `true` | Mini mode click-through |
|
|
| `mini_hover_threshold` | `f32` | `3.0` | Hover delay before drag (1-10 sec) |
|
|
|
|
**General**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `auto_start_on_login` | `bool` | `false` | Launch on Windows startup |
|
|
|
|
**Window Position (internal)**
|
|
|
|
| Key | Type | Default | Description |
|
|
|:----|:-----|:--------|:------------|
|
|
| `main_window_x` | `i32?` | `null` | Main window X position |
|
|
| `main_window_y` | `i32?` | `null` | Main window Y position |
|
|
| `main_window_width` | `u32?` | `null` | Main window width |
|
|
| `main_window_height` | `u32?` | `null` | Main window height |
|
|
| `mini_window_x` | `i32?` | `null` | Mini window X position |
|
|
| `mini_window_y` | `i32?` | `null` | Mini window Y position |
|
|
|
|
</details>
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 📚 Dependencies
|
|
|
|
<details>
|
|
<summary><strong>Rust crates</strong></summary>
|
|
|
|
| Crate | Purpose |
|
|
|:------|:--------|
|
|
| `tauri 2` | Application shell, IPC, multi-window, system tray |
|
|
| `tauri-plugin-shell 2` | Shell integration |
|
|
| `tauri-plugin-notification 2` | Windows toast notifications |
|
|
| `tauri-plugin-global-shortcut 2` | System-wide keyboard shortcuts |
|
|
| `serde` / `serde_json` | Config and stats serialization |
|
|
| `chrono` | Date/time handling for schedules and statistics |
|
|
| `anyhow` | Error handling |
|
|
| `winapi` | Windows idle detection (`GetLastInputInfo`), WebView2 check dialog |
|
|
|
|
</details>
|
|
|
|
<details>
|
|
<summary><strong>JavaScript packages</strong></summary>
|
|
|
|
| Package | Purpose |
|
|
|:--------|:--------|
|
|
| `@tauri-apps/api` | Frontend IPC bindings |
|
|
| `svelte 5` | Reactive UI framework (runes: `$state`, `$derived`, `$effect`) |
|
|
| `tailwindcss 4` | Utility-first CSS |
|
|
| `vite 6` | Build tool and dev server |
|
|
| `motion` | Animation library |
|
|
| `typescript 5` | Type safety |
|
|
|
|
</details>
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 🤝 Contributing
|
|
|
|
This project belongs to no one and everyone. If you find it useful and want to make it better, you are welcome.
|
|
|
|
No contribution agreements to sign. No corporate CLAs. No licensing traps. Everything here is in the public domain. Your contributions will be too - freely given, freely shared, freely built upon by anyone who needs them.
|
|
|
|
**Some ways to help:**
|
|
|
|
- Report bugs or rough edges
|
|
- Suggest new break activities (especially with physiotherapy or ergonomics knowledge)
|
|
- 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
|
|
|
|
The best software is built through mutual aid - people helping people because it's the right thing to do, not because there's a profit motive attached.
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
## 📜 License
|
|
|
|
<p align="center">
|
|
<a href="https://creativecommons.org/publicdomain/zero/1.0/">
|
|
<img src="https://licensebuttons.net/p/zero/1.0/88x31.png" alt="CC0" />
|
|
</a>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<strong>CC0 1.0 Universal - Public Domain Dedication</strong>
|
|
</p>
|
|
|
|
To the extent possible under law, the author has waived all copyright and related or neighboring rights to this work. Published from the commons, for the commons.
|
|
|
|
Copy, modify, distribute, perform - even commercially - all without asking permission. No attribution required (though always appreciated).
|
|
|
|
See [`LICENSE`](LICENSE) for the full legal text.
|
|
|
|
<br />
|
|
|
|
---
|
|
|
|
<p align="center">
|
|
<sub>
|
|
Built with care. Shared without conditions.<br />
|
|
<em>Rest well.</em>
|
|
</sub>
|
|
</p>
|