An audio-driven interval timer, built as an installable Progressive Web App for a phone kept nearby but out of sight and out of hand.
The session runs itself. Voice, a state-matched music bed, vibration, and a full-screen colour flood tell you what to do, so you never have to look at or touch the phone mid-workout.
The voice says only:
| Category | Spoken words |
|---|---|
| State | REST, SPRINT |
| Calls | Drop down, Leap, Roll, Bump |
Nothing else. No "easy now", no "all out", no "go", no "breathe". English, en-US, using a local
offline device voice. Everything else is carried by tone, music, vibration, and colour.
cd "path\to\this\folder"
python -m http.server 8000Open http://localhost:8000. Press START, and the five-second ready countdown leads into the session.
Serve it over HTTP. Opening
index.htmldirectly fromfile://blocks the service worker and the manifest, so offline mode and installation will not work.
Full instructions for hosting, Android installation, and updates live in docs/RUN-AND-INSTALL.md.
- Five-second ready screen. START runs a green GET READY countdown before the session, so you can put the phone down and get into your stance. The workout clock starts at zero.
- Alternating session. Starts in REST and alternates REST / SPRINT until the configured total time is reached. Default 25 minutes.
- Random interval lengths. Every interval is drawn from that state's own probability curve across its min / max range.
- Exact finish. If the next interval would overrun the total, it is trimmed so the workout ends on the second.
- Calls. Extra movements layered on top of the current state. They never interrupt, replace, or straddle REST and SPRINT. No two spoken calls land less than 2.5 s apart. The rep count is never shown — not knowing is part of the training.
- Two-speed music. REST and SPRINT are the same loop at one beat per second and five beats per second. The switch is a hard cut in both directions, so the tempo jump itself encodes the change.
- Pro Mode. Four distribution editors with ten vertical sliders each. The graph is the actual sampling curve, not artwork.
- Fully offline. No backend, no CDN, no network dependency at runtime.
| Path | Purpose |
|---|---|
index.html |
Four screens: settings, ready, workout, summary. Structure only; controls are rendered from data. |
style.css |
Mobile-first, high contrast, state colour flooding. No external fonts. |
app.js |
Registries, probability engine, session engine, audio, speech, haptics, UI. |
manifest.json |
PWA metadata for Android installation. |
service-worker.js |
Cache-first app shell so the whole thing runs in airplane mode. |
icons/ |
192, 512, and maskable 512 PNG icons. |
| Document | Read it for |
|---|---|
| docs/RUN-AND-INSTALL.md | Running locally, deploying to HTTPS, installing on Android, verifying offline, pre-workout checks, shipping updates. |
| docs/HOW-IT-WORKS.md | The probability engine, session timing, call scheduling rules, and the audio architecture. |
| docs/SETTINGS.md | Every setting, what it does, and how Pro Mode curves map to real values. |
| docs/VERIFICATION.md | What was tested in a real browser and the measured results. |
| docs/TROUBLESHOOTING.md | No sound, wrong voice, screen sleeping, stale version after an update. |
A modern mobile browser. Chrome on Android is the target: it supports the Web Audio API, Speech Synthesis, the Vibration API, the Wake Lock API, service workers, and home-screen installation. Desktop Chrome and Edge run everything except vibration.