5.0 KiB
UI redesign delivery notes
Implemented locally on 8 September 2026. No production database or deployment was used.
What changed
- Overview, History and Trends replace the five separate dashboard tabs. Week/month calendars remain available in History, with daily summaries and links to the original readings.
- Shared teal/slate visual system, responsive layouts, system fonts, saved dark mode, consistent form controls, and personal threshold labels.
- Save confirmations now occupy an inline strip below navigation. They cannot overlay Add reading or Save & add another, and remain readable until dismissed or the next navigation.
- Add reading supports Save & add another, numeric mobile inputs, and clear validation. Invalid submissions retain the entered timestamp, and edits correctly save timestamp changes.
- Shared date filtering uses local calendar dates and exclusive next-midnight UTC boundaries, including daylight-saving changes. Ambiguous/skipped entry times show a validation message.
- SVG trends contain at most 180 buckets per series. Longer ranges use labelled multi-day averages; raw readings remain in History and exports. Pulse has its own expandable chart, and a native disclosure exposes chart data for touch/keyboard users.
- Filtered CSV export and a printable HTML summary are available for the selected period. Existing full-history export remains available. Exports retain UTC timestamps for re-imports.
- Import validates headers, measurement ranges and a 2 MB file limit before committing. Import and delete now validate their form CSRF tokens; export streaming retains its request context.
- Ordinary links/forms handle navigation, filtering and downloads. The dashboard arrives complete in one HTML response. Small optional JavaScript handles notification dismissal, account-menu dismissal and the print button.
- Shared assets use fingerprinted URLs. Authenticated page responses use private/no-store caching. No runtime framework, chart package, font or icon library was added.
Size results
Measured using scripts/check-pages.py with deterministic, synthetic SQLite fixtures. Decimal kB; gzip-compressed response bodies, excluding HTTP headers/TLS overhead. A live production transfer capture has not been performed.
| Resource | Raw | Gzip |
|---|---|---|
| Shared CSS | 21,686 B | 5,507 B |
| All JavaScript | 607 B | 315 B |
| Favicon | 276 B | 217 B |
| Typical Overview HTML | 10,643 B | 2,723 B |
| Typical History HTML (25 rows) | 20,222 B | about 2,449 B |
| Large Trends HTML (10,000 readings, 2020–2026 range) | 56,299 B | 8,866 B |
Typical cold Overview total: 8,762 B / 8.8 kB gzip, across four resources and no automatic follow-up fetch. This is comfortably below the proposed 40 kB budget. Compression implementations can differ by a few bytes.
Before this work, shared CSS was 26,156 B raw and the navigation script was 1,384 B raw, plus inline template scripts. CSS is now about 17% smaller; the shared script is about 56% smaller and replaces the inline scripts too. No comparable pre-redesign full-page network capture was taken.
npm run build now fails if compressed CSS exceeds 8 kB or JavaScript exceeds 5 kB. Integration tests and the page measurement script enforce 20 kB page and 40 kB cold Overview limits.
Verification
npm run build: passed, including asset-size budgets. The existing Browserslist data-age warning remains; dependencies were not upgraded for this redesign.venv/Scripts/python.exe -m pytest -q: 42 passed.venv/Scripts/python.exe scripts/check-pages.py: passed for empty, typical and 10,000-reading accounts.- Integration coverage includes date validation, 23/25-hour local days, form validation and timestamp preservation, add/edit/delete, account isolation, CSRF, saved preferences, streaming export, import atomicity, legacy bookmarks, pagination, compression and caching.
- Browser checks used disposable data: Overview at 360/1440 px, calendar at 768 px, saved dark mode across navigation, native Back/Forward pagination, and keyboard activation of chart disclosures.
- Mobile Save & add another was exercised through the browser. The notification's computed position is static, and its bounding rectangle does not intersect the button. Measurement fields reset after a successful save.
- The printable HTML report is covered by the route/filter tests. Actual browser PDF pagination and 200% browser zoom still require a manual check; the available browser controls did not support zoom adjustment.
Run the local preview
From the repository root:
npm run build
venv/Scripts/python.exe scripts/preview.py
Open http://127.0.0.1:5055, then log in with demo / preview-only. The preview uses an in-memory SQLite database with generated readings, binds only to localhost, and loses its data when stopped. It never uses the configured production database.
No schema migration is needed. Optional reading notes, an import preview/duplicate-resolution workflow, and reminders remain follow-up scope, as set out in the implementation plan.