Core Cooldown
A portable break timer for Windows that reminds you to rest.
Because your time and your body belong to you — not to your screen.
---
## Why
Repetitive strain injury and eye strain are not personal failings. They are the predictable consequence of systems that treat human attention as an extractable resource. Every worker 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` with no installer, no account, no telemetry, and no data leaving your machine. Drop it in a folder and run it. It will remind you to rest. That's it.
## Features
### Timer & Breaks
| Feature | Description |
|:--------|:------------|
| **Configurable intervals** | Set work sessions from 5–120 minutes and breaks from 1–60 minutes |
| **Pre-break warnings** | Toast notification and optional sound alert before each break |
| **Break enforcement** | Always-on-top break window, optional fullscreen mode |
| **Strict mode** | When enabled, the skip and cancel buttons are removed entirely |
| **Early end** | Optionally allow ending a break after 50% completion |
| **Snooze** | Delay a break by a configurable number of minutes (with configurable limits) |
| **Skip cooldown** | Prevent rapid-fire skipping with a configurable cooldown timer |
| **Immediate breaks** | Skip the pre-break notification and go straight into the break |
| **Manual break** | Start a break at any time from the dashboard or the tray menu |
### Idle Detection & Smart Breaks
| Feature | Description |
|:--------|:------------|
| **Idle auto-pause** | Detects inactivity via Windows API (`GetLastInputInfo`) and pauses the timer |
| **Auto-resume** | Timer resumes automatically when you return |
| **Smart breaks** | Recognizes natural breaks (stepping away from the keyboard) and optionally counts them toward your daily goal |
| **Configurable thresholds** | Idle timeout (30–600s) and smart break threshold (2–15 min) are independently adjustable |
### Break Activities
Each break screen shows a randomized activity suggestion from a curated library of **70 activities** across four categories:
- **Eyes** — palming, distance focusing, figure-eights, warm compress visualization, peripheral awareness drills
- **Stretch** — neck rolls, wrist flexion, shoulder blade squeezes, chest openers, spinal twists, hip flexor stretches
- **Breathing** — box breathing, 4-7-8 technique, alternate nostril, diaphragmatic breathing, resonance breathing
- **Movement** — standing calf raises, wall push-ups, balance exercises, gentle squats, toe touches, desk yoga
Activities cycle every 30 seconds and never repeat consecutively.
### Working Hours Schedule
A per-day schedule with support for multiple time ranges per day. The timer only runs during your configured working hours — outside of 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 are disabled by default
### 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 breaks to total scheduled |
| **Streak tracking** | Current and best consecutive-day streaks |
| **7-day chart** | Canvas-rendered bar chart showing daily break history |
All statistics are stored locally in a plain JSON file next to the executable.
### Sound Effects
Synthesized notification sounds via the Web Audio API — no bundled audio files, no network requests.
**8 presets:** Bell, Chime, Soft, Digital, Harp, Bowl, Rain, Whistle
Each preset plays on break start, pre-break warning, and break completion. Volume is configurable from 0–100%.
### Global Keyboard Shortcuts
| Shortcut | Action |
|:---------|:-------|
| `Ctrl + Shift + P` | Pause / resume timer |
| `Ctrl + Shift + B` | Start break now |
| `Ctrl + Shift + S` | Show / hide main window |
These work system-wide, even when Core Cooldown is not focused.
### System Tray
- **Dynamic icon** — a 32×32 progress arc rendered in real-time: orange during focus, purple during breaks, dimmed when paused
- **Countdown tooltip** — hover over the tray icon to see time remaining
- **Context menu** — pause/resume, start break, toggle mini mode, show/hide, quit
### Mini Mode
A compact floating timer (200×50px) that sits on top of your other windows.
- **Click-through** — the mini timer is completely transparent to mouse events by default, so it never blocks what's underneath
- **Hover to grab** — hover over it for a configurable number of seconds (default: 3) and it becomes draggable
- **Double-click** — opens the main window
- **Togglable** — enable/disable from the tray menu
### Appearance & Customization
| Setting | Range |
|:--------|:------|
| **UI zoom** | 50–200% with live preview |
| **Accent color** | Hex color picker for the main UI accent |
| **Break color** | Separate hex color for the break screen ring |
| **Color schemes** | Ocean, Forest, Sunset, Midnight, Dawn |
| **Countdown font** | Google Fonts selector for the timer display |
| **Background blobs** | Animated gradient blobs with film grain overlay |
| **Backdrop opacity** | 50–100% for the break screen overlay |
| **Break title & message** | Fully customizable text shown during breaks |
| **Dark mode** | Always on (it's the only civilized option) |
### Notifications
Native Windows toast notifications for:
- Pre-break warnings (configurable seconds before break)
- Break completion
### Window Behavior
- **Frameless window** with custom titlebar and drag region
- **Transparent background** with frosted glass effects
- **Window position persistence** — main and mini windows remember their position between launches
- **Animated view transitions** — directional fly/scale/fade transitions (700ms, cubicOut easing) between all views
## Portability
Core Cooldown is fully portable. The executable carries everything it needs and stores everything it creates right next to itself:
```
core-cooldown.exe ← the application
config.json ← your settings (created on first run)
stats.json ← your break history (created on first run)
data/ ← WebView2 runtime data (created on first run)
```
No installer. No registry entries. No writes to `%APPDATA%`, `%LOCALAPPDATA%`, or any other system directory. Move the folder anywhere — a USB stick, a shared drive, a different machine. It just works.
There is nothing to uninstall. Delete the folder and it's gone. No traces left behind.
## Installation
1. Download `core-cooldown.exe` from the [Releases](../../releases) page
2. Put it in any folder you like
3. Run it
That's it. No elevated permissions required. No runtime dependencies to install. The first launch may take a moment while Windows initializes the WebView2 runtime.
## Building from Source
### Prerequisites
- **Node.js** (v18+) and **npm**
- **Rust** toolchain (`rustup`) with the `x86_64-pc-windows-gnu` target
- **MinGW-w64** — the GNU toolchain for Windows (provides the linker, windres, and dlltool)
### Setup
```bash
# Clone the repository
git clone https://git.lashman.live/lashman/core-cooldown.git
cd core-cooldown
# Install JavaScript dependencies
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 the app with hot-reload
npm run tauri dev
# Check Rust code without building
cd src-tauri && cargo check
# Build frontend only (no Tauri shell)
npm run dev
```
### Release Build
```bash
# Build a release executable (no installer)
npm run tauri build
```
The compiled binary will be at:
```
src-tauri/target/x86_64-pc-windows-gnu/release/core-cooldown.exe
```
## Architecture
Core Cooldown is a split-architecture desktop application: a Rust backend for system integration and timer logic, and a Svelte frontend rendered in a native WebView.
```
┌──────────────────────────────────────────────────────────────┐
│ System Tray │
│ (dynamic icon · tooltip · menu) │
├──────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Main Window │ │ Break Window│ │ Mini Window │ │
│ │ (WebView) │ │ (WebView) │ │ (WebView) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────┬───────┴──────────────────┘ │
│ │ Tauri IPC (commands + events) │
│ ┌─────────┴─────────┐ │
│ │ Rust Backend │ │
│ │ │ │
│ │ TimerManager │ ← state machine (tick/sec) │
│ │ Config │ ← JSON persistence │
│ │ Stats │ ← break history tracking │
│ │ IdleDetector │ ← GetLastInputInfo polling │
│ │ GlobalShortcuts │ ← Ctrl+Shift+P/B/S │
│ │ TrayIcon │ ← RGBA ring rendering │
│ │ Notifications │ ← Windows toast │
│ └───────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────┘
```
### Backend (Rust)
| Module | Responsibility |
|:-------|:---------------|
| `lib.rs` | Tauri app builder, command registration, tray setup, timer tick thread, window management, global shortcuts |
| `config.rs` | Configuration struct with serde serialization, validation (clamping all values to safe ranges), and file I/O |
| `timer.rs` | Timer state machine (`Running` → `Paused` → `BreakActive`), idle detection via Windows API, working hours enforcement |
| `stats.rs` | Daily break statistics, streak calculation, history queries |
| `main.rs` | Entry point |
### Frontend (Svelte 5 + TypeScript)
| Layer | Files |
|:------|:------|
| **Views** | `Dashboard.svelte`, `BreakScreen.svelte`, `Settings.svelte`, `StatsView.svelte` |
| **Windows** | `BreakWindow.svelte` (standalone break modal), `MiniTimer.svelte` (floating mini mode) |
| **Components** | `TimerRing.svelte`, `Titlebar.svelte`, `ToggleSwitch.svelte`, `Stepper.svelte`, `ColorPicker.svelte`, `FontSelector.svelte`, `TimeSpinner.svelte`, `BackgroundBlobs.svelte` |
| **Stores** | `timer.ts` (reactive timer state from IPC events), `config.ts` (config state with debounced auto-save) |
| **Utilities** | `sounds.ts` (Web Audio synthesis), `activities.ts` (70 break activities), `animate.ts` (motion library actions) |
### IPC Contract
**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`
**Events** (backend → frontend):
`timer-tick` (every second), `break-started`, `break-ended`, `prebreak-warning`, `config-changed`
## Configuration Reference
All settings are 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 if you prefer.
Full configuration schema
| Key | Type | Default | Range | Description |
|:----|:-----|:--------|:------|:------------|
| `break_duration` | `u32` | `5` | 1–60 min | Duration of each break |
| `break_frequency` | `u32` | `25` | 5–120 min | Interval between breaks |
| `auto_start` | `bool` | `true` | — | Start timer on launch |
| `break_title` | `string` | `"Rest your eyes"` | max 100 chars | Title shown on break screen |
| `break_message` | `string` | `"Look away from the screen..."` | max 500 chars | Message shown during breaks |
| `fullscreen_mode` | `bool` | `true` | — | Use fullscreen break window |
| `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 |
| `working_hours_enabled` | `bool` | `false` | — | Restrict timer to schedule |
| `working_hours_schedule` | `array` | Mon–Fri 09:00–18:00 | 7 days | Per-day time ranges |
| `dark_mode` | `bool` | `true` | — | Dark theme |
| `color_scheme` | `string` | `"Ocean"` | 5 presets | Color scheme name |
| `backdrop_opacity` | `f32` | `0.92` | 0.5–1.0 | Break screen backdrop opacity |
| `notification_enabled` | `bool` | `true` | — | Enable toast notifications |
| `notification_before_break` | `u32` | `30` | 0–300 sec | Pre-break warning time |
| `snooze_duration` | `u32` | `5` | 1–30 min | Snooze delay |
| `snooze_limit` | `u32` | `3` | 0–5 (0=unlimited) | Max snoozes per cycle |
| `skip_cooldown` | `u32` | `60` | 0–600 sec | Cooldown between skips |
| `sound_enabled` | `bool` | `true` | — | Play notification sounds |
| `sound_volume` | `u32` | `70` | 0–100 | Sound volume percentage |
| `sound_preset` | `string` | `"bell"` | 8 presets | Sound preset name |
| `idle_detection_enabled` | `bool` | `true` | — | Enable idle auto-pause |
| `idle_timeout` | `u32` | `120` | 30–600 sec | Idle threshold |
| `smart_breaks_enabled` | `bool` | `true` | — | Detect natural breaks |
| `smart_break_threshold` | `u32` | `300` | 120–900 sec | Natural break threshold |
| `smart_break_count_stats` | `bool` | `false` | — | Count natural breaks in stats |
| `show_break_activities` | `bool` | `true` | — | Show activity suggestions |
| `ui_zoom` | `u32` | `100` | 50–200% | Interface zoom level |
| `accent_color` | `string` | `"#ff4d00"` | hex | Main accent color |
| `break_color` | `string` | `"#7c6aef"` | hex | Break screen ring color |
| `countdown_font` | `string` | `""` | font family | Google Font for countdown |
| `background_blobs_enabled` | `bool` | `false` | — | Animated background blobs |
| `mini_click_through` | `bool` | `true` | — | Mini mode click-through |
| `mini_hover_threshold` | `f32` | `3.0` | 1.0–10.0 sec | Hover time before drag |
## Dependencies
### Rust
| 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` | Configuration and statistics serialization |
| `chrono` | Date/time handling for schedules and statistics |
| `dirs` | Platform directory resolution (unused — legacy dep) |
| `anyhow` | Error handling |
| `winapi` | Windows idle detection (`GetLastInputInfo`) |
### JavaScript
| 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 |
## Contributing
This project belongs to no one and everyone. If you find it useful and want to make it better, you are welcome.
There are 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 if you have physiotherapy or ergonomics knowledge)
- Improve accessibility
- 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.
## 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 be able to 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.
We believe that tools for human wellbeing should never be enclosed, never be scarce, and never serve a master other than the person using them.
## License
**CC0 1.0 Universal — Public Domain Dedication**
To the extent possible under law, the author has waived all copyright and related or neighboring rights to this work. This work is published from the commons, for the commons.
You can copy, modify, distribute, and perform the work, even for commercial purposes, all without asking permission. No permission is needed. No attribution is required (though it's always appreciated).
See [`LICENSE`](LICENSE) for the full legal text.
---
Built with care. Shared without conditions.
Rest well.