Skip to content

Repository files navigation

Exercises.

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 gist scope 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.

Enable GitHub Pages (one-time)

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.

Exercise figures (Gemini "Nano Banana")

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.comGet 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.

Develop

Serve the folder with any static server and open it:

python3 -m http.server 8000

Structure

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)

Reference

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.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages