Glow Up Habit Tracker. The home screen icon says "Glow Up", because a home screen label truncates at about twelve characters and "Glow Up habit tra..." is not a name.
A habit tracker whose weekly overview is the whole app: a grid of habits by day, filled when done.
The one twist is in the name. A mark physically glows on an HDR-capable screen, brighter than white, the way an HDR photo does in Photos.
Light marks the habit: today's slot glows because it is still actionable, and every completion glows too, whatever day it fell on. What stays dark is what never happened — a missed day, a day still to come. Open and done are told apart by shape rather than by brightness: a ring against a dot in the week grid, an outlined band against a line on the Today ring.
Working name. Rename freely.
| Phase | What it is | State |
|---|---|---|
| 0 | Glow spike: prove the glow really glows | Confirmed on device |
| 1 | Core app: CRUD, persistence, weekly grid, tap to complete | Done |
| 2 | Glow integration: open state and the completion transition | Done |
| 3 | Polish: app icon, empty state, reordering, visual pass | Done |
The glow is confirmed working on an iPhone 14 Pro: with it on screen, the
system's granted EDR headroom rises from 1.2 to 6.0, which is exactly what the
renderer asks for. Getting there meant abandoning the gain-map approach for PQ,
because every gain-map encoding came back from UIImage.isHighDynamicRange as
false. See docs/glow.md, which is worth reading before touching
anything HDR.
The Xcode project is generated and is not in the repository, so generate it first:
Tools/generate.shThat is the only supported way to generate the project, and it needs no
brew install: the XcodeGen it uses is pinned by version and by the digest of
its release archive in Tools/xcodegen.pin, and downloaded into a gitignored
cache on first use.
Running xcodegen generate yourself produces a project that opens, builds and
is wrong on the phone. The script repairs one value xcodegen cannot write in the
form Xcode reads — the App Groups capability, without which codesign strips the
entitlement and the widget stops seeing the store — and then reads the result
back as a property list and fails if that capability, the entitlement or the
widget's extension-only API enforcement is not really there. See the script for
what and why.
Then open Glow.xcodeproj, or just run the tests:
Tools/test.shTo run on a real phone, which is the only way to see the glow, create a
Local.xcconfig with your team and regenerate:
echo "DEVELOPMENT_TEAM = YOURTEAMID" > Local.xcconfig && Tools/generate.shThat file is gitignored, because a team ID is an account identifier rather than a project fact. Everything else, simulator included, works without it.
Regenerate (Tools/generate.sh) after any change to project.yml, and after switching to a branch
that has different files: the generated project keeps pointing at whatever
existed when it was made, and the resulting failure reads like a missing file
rather than a stale project.
Glow/Logic/ Pure logic: weeks, slot states, row geometry. No UI, no store.
Glow/Glow/ The HDR glow: renderer, cache, accents.
Glow/Models/ SwiftData models.
Glow/Store/ Every write to the store.
Glow/Views/ SwiftUI.
GlowWidget/ Home screen widget. Shares Logic, Models and Store with the app.
Glow/Resources/ Asset catalogue. The app icon is generated by Tools/make-app-icon.swift.
Tests/ Swift Testing. No device needed.
Tools/test.sh The test command.
The split that matters is Logic/: it holds every decision the grid makes and
depends on neither SwiftData nor SwiftUI, so the rules can be tested directly
rather than through a view. Views/ is then mostly layout, and a view never
works out for itself which day a tap belongs to.
- SPEC.md is the product truth: what the app does and what it deliberately does not.
- docs/ARCHITECTURE.md is the technical truth.
- docs/glow.md is the HDR technique, what was verified and how, and the parts that only a real screen can answer.
- docs/decisions.md records the open questions from the spec and what they were resolved to.
Most of the code here was written by Claude Opus 5 under direction. The commit log records it in git's own terms rather than in a footnote: Claude is the author of a commit it wrote, and the committer is whoever applied it.