A minimalist exercise tracker PWA — Gym / Stretching / Calisthenics as a compact grid, every exercise with its own AI-illustrated figure and real working weights. Tap an exercise → fullscreen player: pick reps, hit Done, and it auto-advances to the next one (timers start and log themselves). Includes a guided "Corpo" stretching routine — four ~30-minute series (feet · psoas & hamstrings · front split · pancake & glutes) — built from the Corpo playlist.
Live: https://gabrielom.github.io/exercises/ · Plan: PLAN.html
- All data stays on your device (
localStorage), with JSON export/import backup. - Cross-device sync (optional): History → Sync. Create a classic GitHub
personal access token with only the
gistscope and paste it once per device; the app stores your history in a private gist and union-merges on every sync (append-only log — no conflicts). Auto-syncs on open and after each set. The token never leaves the device and is excluded from export backups. - Installable: open the live URL on your phone → share menu → Add to Home Screen → launches standalone and works offline.
- No build step, no framework, no dependencies.
Repo Settings → Pages → Build and deployment → Source: Deploy from a branch → main / (root) → Save.
The site appears at https://gabrielom.github.io/exercises/ a minute later.
Every figure is an AI illustration generated by Gemini Flash Image and stored as
a transparent WebP in img/gen/<id>.webp (what the app loads — see imgFor in
js/data.js). To (re)generate art, get an API key at
aistudio.google.com → Get API key, then:
GEMINI_API_KEY=AIza... node tools/genimages.mjs push-up pigeon # try a few
cp img/gen/push-up.png img/gen/_anchor.png # lock the style
GEMINI_API_KEY=AIza... node tools/genimages.mjs # the rest match it
node tools/optimize.mjs # png → 768px transparent webp
genimages.mjs writes img/gen/<id>.png; optimize.mjs shrinks each to the
transparent .webp the app serves and deletes the png. Delete an image and
rerun to redo it (--force regenerates). Commit img/gen/ and bump VERSION
in sw.js to deploy.
Serve the folder with any static server and open it:
python3 -m http.server 8000
index.html app shell
css/style.css theme + masonry layout
js/data.js exercise catalog (real gym program + weights) + Corpo routine
js/app.js grid, fullscreen auto-advancing player, history, export/import
js/routine.js guided hold / rest routine player
js/store.js localStorage state + logging
js/sync.js optional private-gist cross-device sync
img/gen/ 120 generated exercise figures (transparent WebP)
tools/genimages.mjs figure generator (Gemini "Nano Banana")
tools/optimize.mjs png → transparent 768px WebP
sw.js offline cache (bump VERSION to deploy updates)
manifest.webmanifest PWA manifest
PLAN.html project plan & full routine table
docs/HANDOFF.md initial reference handoff (from the original build thread)
docs/HANDOFF.md is the initial handoff for this project, written in
an earlier chat thread — the session that first designed and built the app. It holds the
original brief, the decisions behind it, the full gym catalog and the scraped "Corpo"
playlist the stretching routine came from. It describes the July 2026 state and is kept
unedited — see docs/README.md for what has changed since.