CalmCheck — Panic help in 60 seconds, fully offline
Inspiration
Mental-health apps are built for maintenance — daily check-ins, streaks, dashboards. The moment that actually matters is different: someone is in distress right now and needs to know exactly what to do in the next 60 seconds. That moment has no bandwidth for menus, accounts, or spinners over a dead wifi logo.
CalmCheck answers it in two halves:
- Calm yourself — a guided panic flow: paced breathing with synchronized haptics and voice, plus 5-4-3-2-1 sensory grounding.
- Be ready for someone else — Care Cards: a structured, shareable offline profile for a person you look after, readable by any caregiver or stranger in seconds via QR code.
Everything works in airplane mode, on principle.
What we learned
The breathing pacing had to be grounded in physiology, not taste. Slow breathing near resonance frequency (~6 breaths/min) maximizes parasympathetic influence:
$$T_{\text{cycle}} = 4\,\text{s} + 6\,\text{s} = 10\,\text{s} \;\Rightarrow\; f = \frac{60}{10} = 6\ \text{breaths/min}$$
Haptic pulses are scheduled on a phase function, not a fixed timer, so the pacer stays in sync even if the event loop stalls:
$$\phi(t) = \frac{t \bmod T_{\text{cycle}}}{T_{\text{cycle}}}, \qquad \text{haptic at } \phi = 0,\ 0.4$$
Other lessons:
- An app that promises "no internet, no data collection" must prove it — ML Kit quietly re-added
INTERNETto our release build. - Offline-first is a hard constraint, not a feature flag. The result is a ~24–28 MB minified APK that needs nothing at runtime.
- The "Field Card" design system was developed across 9 structured design sessions, ending with a dedicated accessibility pass.
How we built it
- Flutter, offline-first, ~226 tests,
flutter analyzeclean. - Billing via
in_app_purchase; free tier genuinely includes one free card, plus a giveback mechanic. - Store-ready: signed release builds, R8-minified, iOS 14+ / Android 7+, with a full submission checklist.
- A render-shots test outputs a dozen screens as PNGs with real bundled fonts, so QA can look at builds, not only assert on them.
Challenges
Before shipping, a full production-readiness audit surfaced 37 findings the tooling couldn't catch — including a free-tier bug that paywalled every new user, cold starts silently granting Pro, crisis "Call" buttons doing nothing on tablets without telephony, and a location timeout that expired while the OS permission dialog was still open — exactly on the panic path.
Three taught us the most:
- Entitlements are a race. Pro must survive store-query latency and be revocable on refund — both directions of the same rule: never trust stale or unknown entitlement state.
- Safety-critical flows need failure design. Silent no-ops on "Call" and first-press location were the least acceptable places for our app to fail.
- Release builds break differently. Missing R8 rules crashed reminders in release only; every debug test was green.
All 37 findings were fixed, and the app was walked end-to-end on a minified release build on a real emulator before submission.
Accomplishments that we're proud of
What we learned
What's next for CalmCheck
Built With
- claude
- flutter
- lovable
Log in or sign up for Devpost to join the conversation.