Overview
Savings Calculator is a small tool for the "save an increasing amount each day of the month" challenge — set a base amount and the number of days, and it shows the running total as the daily saving scales up (£1 on day one, £2 on day two, and so on). It started as a quick single-purpose build and later went through a full redesign pass that's more interesting than the calculator itself: a dark theme rebuild alongside a genuine Web Interface Guidelines and accessibility audit.
The problem
The original version worked but had the kind of issues that accumulate in a "just get it working" build: a generic font, an outline: none on focusable elements with nothing put back in its place, no live region announcing the result as it updates, and missing the small semantic details (input autocomplete attributes, a proper page title, table scope attributes) that don't affect whether something functions but do affect whether it's actually usable by everyone.
What I did
A real redesign, not just a colour swap
The CSS overhaul replaced the original Dosis font with Inter, rebuilt the styling around an emerald-green savings theme, added font-variant-numeric so the running-total figures align properly as tabular numbers, and used text-wrap: balance on headings so they don't break awkwardly. It's a small project, but the redesign commit touches 320 lines of CSS — treating a "just a calculator" project's visual polish with the same care as production work.
Fixing the outline: none anti-pattern
The original build had removed the default focus outline without replacing it — a common but genuinely harmful pattern that leaves keyboard users with no visible indication of where focus is. I replaced it with :focus-visible and an accessible focus ring, which keeps the outline gone for mouse users (who don't need it) while keeping it fully visible for keyboard navigation (who do).
Accessibility details that don't show up in a screenshot
An aria-live region on the result so the total is announced as it changes, semantic <main> and <section> elements instead of generic <div>s, scope attributes on the results table's header cells, and name/autoComplete attributes on the inputs. Individually tiny; together, the difference between a page that merely renders correctly and one that's actually navigable with a screen reader or keyboard alone.
Respecting reduced motion
Added prefers-reduced-motion support so any transition or animation backs off for users who've asked their OS not to show them motion. It's a single media query, and it's the kind of thing that's trivial to add and easy to forget entirely if accessibility isn't a habitual check before shipping.
Engineering decisions
Treating a personal utility to the same bar as client work
Nothing about this project needed to be accessible or polished — it's a savings calculator for personal use. I redid it anyway, because the habits that matter on a production client site (focus management, semantic HTML, live regions) are habits, not situational choices, and the cheapest place to practice them is a project with no deadline and no stakeholder pressure.
Font preconnect and page metadata as part of the same pass
Alongside the visual and accessibility work, the redesign added a font preconnect link and fixed the page title — small performance and metadata details that get skipped when a project starts as a quick build and never gets a second pass. Bundling these into the same commit as the accessibility fixes reflects how I actually think about a "redesign": it's not just new CSS, it's everything that was cut corners on the first time through.
Stack
| Layer | Choice |
|---|---|
| Framework | React · TypeScript · Vite |
| Styling | Plain CSS, custom dark theme |
| Font | Inter |
Reflections
This is a two-commit project, and the second commit is the one worth talking about. It's a useful reminder that "redesign" doesn't have to mean a new feature set — sometimes it means going back over something that already works and asking whether it actually holds up against the standards you'd apply to anything else, focus states, semantics, motion preferences included. A savings calculator doesn't need any of that to function. It needs it to be something you'd be comfortable calling finished.