Skip to content

Releases: kimhinton/keystrum

v0.2.0 — Practice mode upgrades + wellbeing pass

Choose a tag to compare

@kimhinton kimhinton released this 30 Apr 06:35

v0.2.0 — Practice mode upgrades + wellbeing pass

Released 2026-04-30. Effective milestone coverage 4/5: 3 closed (#14 / #19 / #21), 1 partial (#15 — height ✓, width follow-up → v0.3.0), 1 deferred (#23 → post-PMF).

Practice mode

  • Opt-in metronome (#19) — Ready-Up screen toggle, 4-on-the-floor click sync'd to song.bpm. Downbeat 1200 Hz accent, off-beats 800 Hz tick. Persisted via zustand. (Hebbian rationale: simultaneous beat-click + visual key cue + key input strengthens procedural memory.)
  • Fourth song: Britpop 4-chord (Em-G-Dm-C) (#14) — at /play/britpop-jam. The progression behind Wonderwall and many other 1990s Britpop songs. D substituted with Dm to fit the keystrum 6-chord set.

PWA & mobile

  • PWA install prompt deferred until first chord played (#21) — Mobile fallback modal no longer surfaces Install as app on first visit; appears only after firstAudioAt !== null.
  • 44 px tap-target height on narrow viewports (#15 partial) — min-h-11 sm:min-h-0 enforced on KeyboardGuitar keys, satisfying Apple HIG / WCAG 2.5.5 vertically. Width on iPhone SE / 375 px stays narrow because 13 columns must fit; full layout redesign tracked in v0.3.0.

Accessibility

  • WCAG 2.1 A/AA cleanaxe-core CI now runs weekly + on workflow_dispatch. 12 violations → 0 across all six pages (viewport, contrast, opacity, hint colors, step-number tracking).
  • ARIA additionsRecallSession role=status aria-live=polite, FinishedScreen role=region, KeyboardGuitar role=application. Covers dynamic content the static checker can't see.

Visual polish

  • Brand-color migration — 21 source files, ~85 occurrences of hardcoded `#FF3864` / `#FF5680` consolidated to a single `--brand` CSS variable (Tailwind v4 `@theme inline`). Future warm-wood A/B = one-line edit.
  • Long-form typography — `max-w-prose` + `leading-relaxed` on chord theory and FAQ answers.
  • PWA manifest enrichment — `id`, `scope`, `orientation`, `lang`, `dir`, three screenshots, three shortcuts, maskable icons. Service worker bumped to `CACHE_NAME v2`, pre-cache extended to `/me`, `/about`, `/privacy`.
  • Unity footer — homepage adds "From one keyboard guitarist to another."

Wellbeing

  • 25-minute session-break nudge — soft, dismissible reminder on every route after a tab has been open ~25 min. Postpones for another 25 min on dismiss. (Cortisol / dlPFC fatigue rationale.)
  • Wellbeing principles in CONTRIBUTING.md (no forced missions / no push / no ads / no dark patterns / silent failure / dlPFC fatigue acknowledgment) and a Wellbeing first paragraph in README.md. The 25-min nudge is the only notification keystrum will ever send.
  • Reference-dependence delta on /me — Today / Yesterday line above the heatmap. `+Δ over yesterday` shown only when delta is positive; negative delta is not framed as a loss (no streak guilt).
  • No account, no lock-in in 3-page footers.
  • Game burst label — `STRUM FAIL` → `STRUM MISS` for tone alignment with the other miss labels.

Documentation

  • BMC strategy notesdocs/business/cs.md (Customer Segments 4-tier × 4-axis, ARPU [BLOCKED] per no-monetization stance) + docs/business/vp-statement.md (Geoffrey-Moore template + 11-element self-evaluation).
  • Response time in CONTRIBUTING.md — 24-48 h first response, single maintainer, blocking-bug fast-lane.

Deferred to v0.3.0 / post-PMF

  • #15 width — full layout redesign (drop number row on narrow viewports, or overflow-x-auto with sticky chord legend).
  • #23 Light/dark theme — infrastructure (CSS-vars + .dark class) is in place; ~50 hardcoded bg-[#0E0E12] / text-neutral-{100..400} references need page-level migration. Pre-PMF over-engineering; revisit at ~50 active users.

🤖 Generated with Claude Code

v0.1.0 — initial public release

Choose a tag to compare

@kimhinton kimhinton released this 29 Apr 07:17

Changelog

All notable changes to keystrum are documented in this file.
The format is based on Keep a Changelog,
and this project adheres to Semantic Versioning.

[0.1.0] — 2026-04-29

Initial public release.

Added

  • 4-row × 6-column QWERTY keyboard mapping (4 strings × 6 chords)
  • Six diatonic chords: Am, C, Em, G, Dm, F (C major / A minor)
  • Karplus-Strong physical-modeling synthesis running live in Web Audio
  • Real strum detection — sweep 3+ keys within 90 ms triggers a chord strum
  • Three demo songs in practice mode: House of the Rising Sun, Scarborough Fair, Greensleeves
  • Active recall practice mode — 5-minute interval prompts (default ON, skippable)
  • /me dashboard with persisted stats (Stored Value): chord plays per chord, day activity heatmap, streak, saved progressions
  • Chord progression sharing via ?prog= URL parameter (e.g. keystrum.app/?prog=Am-F-C-G)
  • Per-chord theory pages at /chords/[name] — chord function, common mistakes, songs that use it
  • ELM dual-route hero — peripheral (auto first sound) + central (Why QWERTY toggle, 3 reasons)
  • PWA support (offline-capable, installable, manifest + service worker)
  • Native iOS and Android apps via Capacitor — same source, single build
  • 11 npm keywords for discoverability (qwerty-instrument, browser-guitar, guitar-chord-practice, chord-trainer, karplus-strong, web-audio-synthesis, web-audio, strum, keyboard-instrument, music, nextjs)
  • 12 GitHub Topics for repository discoverability
  • Schema.org structured data: WebSite, Organization, SoftwareApplication, FAQPage
  • llms.txt + sitemap.xml for AI search indexing

Changed

  • All chord URLs normalized to lowercase + dashes (e.g. /chords/am, /chords/c-major) with 301 redirects from any uppercase variants — fixes the 50 % indexation rate that came from inconsistent external links

Fixed

  • CI restored after 3 commits of failure: cleared the React 19 / Next 16 react-hooks/set-state-in-effect lint error on /me hydration, plus 5 pre-existing lint warnings (unused vars, missing effect deps, unstable useCallback dep)
  • Removed buggy SearchAction schema (the site has no search feature) so Google stops trying to index a non-existent endpoint
  • Twitter card now points to the actual handle @RBlue7681 instead of the never-registered @keystrum_app

Notes

  • Project age at release: 14 days from first commit
  • Solo built, MIT licensed, no payment gating
  • 0 errors / 0 warnings on pnpm lint
  • CI + Deploy passing on every commit since lint cleanup