7b7181126239b42520ba4bae4bcc748721d67bc2
Sub-project 2 of 4 of the visual redesign. Spec in docs/superpowers/specs/2026-09-02-month-view-design.md; the owner chose each of the three directions from concrete alternatives. Three problems, all found by looking at the rendered page rather than at the code: - The totals block was four peer figures with no relationship between them, and the income *input* sat in the same visual register as three numbers derived from it. Nothing answered PRODUCT.md's second question at the month level: with Transport at -3,200 you had to read down the Remaining column to find out. It now reads income -> allocation meter -> spend, with the overspent-post count stated in both directions. - The carry meter rendered 21px below its own row and 22px above the next, so it read as a divider rather than as a property of a post. One tbody per post now holds the figures AND their meter, which is both what pulls it tight under its own row and the only way to hover the pair as one block. - Phone width was broken and nothing recorded it: the 5-column table overflowed at 390px with Spent and Remaining off-screen, and every figure wrapped its currency onto a second line. Below sm: each post is now a two-line block, and the currency is stated once in the legend because every figure in that table is base currency. Meter geometry moves to src/ui/meterSegments.ts, pure and tested, with <Meter> as the only thing that paints it. The allocation meter scales to max(income, allocated) so over-allocating overflows instead of capping at a full bar — over-budget is always allowed, so it has to be drawable. Negatives clamp rather than invert: a segment of negative width puts the gradient's stops out of order, which paints something arbitrary instead of failing. Rejected: one reflowing CSS grid carrying role="table". It deduplicates the markup, but at 390px the layout genuinely is not a table any more, and table roles would describe rows and columns to a screen reader that no longer exist on screen. Verified: 443 tests, tsc clean, build clean, and read in both themes at 1280px and 390px. Not verified, because it is not verifiable here — whether it reads better than what it replaced. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Budget 2.0
A personal budgeting PWA. Envelope-style monthly budgets with rollover, split purchases, finance plans, multi-currency, and JSON/ODS export. All data lives in your browser — there is no server and no account.
Development
bun install
bun --hot src/index.ts # dev server with hot reload
bun test # run the test suite
bun run build # production build into dist/
Self-hosting with Docker
docker build -t budget2 .
docker run --rm -p 3000:3000 budget2
To serve from a subpath, build and run with BUN_PUBLIC_BASE_PATH:
docker build -t budget2 --build-arg BUN_PUBLIC_BASE_PATH=/budget/ .
docker run --rm -p 3000:3000 -e BUN_PUBLIC_BASE_PATH=/budget/ budget2
GitHub Pages
Pushing to main builds and deploys to Pages automatically, using
/<repository-name>/ as the base path. Enable Pages with "GitHub Actions" as
the source in the repository settings.
Your data
Everything is stored in this browser's IndexedDB. Export regularly from Settings → Your data: the JSON export is both your backup and how you move your budget to another device. Import replaces everything and downloads a backup of your current data first.
Known limitations
- Data is per-browser. There is no account and no sync. If you clear this browser's site data, or move to a different browser or device, your budget is gone unless you exported it first. The JSON export is not just a nice-to-have backup — it is the only way to move a budget between devices.
- The install prompt is incomplete.
manifest.webmanifestcurrently only ships an SVG icon. Chrome requires PNG icons at 192×192 and 512×512 to offer the "Install app" prompt; until those are added, the app works fine as a regular tab but won't be installable on Chrome/Chromium.
Documentation
- Design:
docs/superpowers/specs/2026-09-01-budget-app-design.md - Implementation plan:
docs/superpowers/plans/2026-09-01-budget-app.md
Languages
TypeScript
98.3%
CSS
1.4%
HTML
0.2%