8000 feat(app): monochrome design system drawn from the product mark by shroominic · Pull Request #122 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions docs/architecture/adr/0005-monochrome-design-system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# ADR 0005: Express glucose state through a monochrome design system

- Status: Proposed
- Date: 2026-09-16
- Owners: `@shroominic`

## Context

OpenGlucose grew a palette of teal, cream, amber, and coral accents that each
screen redefined locally. Roughly 200 literal colour values were spread across
the app, so a single visual change had to be repeated in every widget and the
result drifted between surfaces.

The palette also carried meaning. A reading was in range because it was teal
and out of range because it was amber or coral. Glucose is health information
that people read quickly, often outdoors, sometimes on a dimmed or greyscale
screen, and about one in twelve men has a colour-vision difference. Hue alone
is a fragile carrier for that state.

The product already has a distinctive mark: a black disc with a white
rounded-square cutout. Nothing in the interface referenced it.

## Decision

The app uses one ink (`#0A0A0A`), one paper (`#FFFFFF`), and a four-step grey
ramp between them. All tokens live in `openhealth/lib/src/theme/og_theme.dart`
and are the only source of colour, radius, and component shape. Feature code
references tokens and does not declare literal colours.

State is carried by contrast, weight, and shape rather than hue:

1. **Filled means present.** A solid mark means live, in range, or improved.
2. **Hollow means attention.** An outlined mark means warming up, waiting,
out of range, or worse than the previous period.
3. **Inversion means importance.** A claim the reader must not miss, such as
demo or sample data, becomes white on an ink bar rather than a colour.

The logo's cutout square is the app's single status glyph. It appears in the
session stage pill, the sensor lifecycle pill, weekly-recap deltas, and notice
bars. The mark itself is drawn in code so it stays crisp at any size and
inverts on ink surfaces.

The glucose chart follows the same rule. The trace is an ink line, the target
band is a light grey block, in-range readings are solid dots, and out-of-range
readings are hollow rings.

This is presentation only. It does not change sensor behaviour, Bluetooth
pairing, stored readings, exports, Health integration, or any privacy control.

## Alternatives considered

- **Keep the accent palette and only unify the tokens:** removes the drift but
keeps hue as the sole carrier of range state.
- **Monochrome surfaces with colour reserved for range state:** reads well for
most people, but still fails on a greyscale or dimmed screen and re-teaches
the reader that colour is a clinical signal.
- **Add a dark theme in the same change:** doubles the review surface. The
token layer is a prerequisite and is introduced here first.
- **Adopt an off-the-shelf design system:** supplies components but not a
visual identity, and would not connect the interface to the product mark.

## Consequences

- New UI must take colour, radius, and component shape from the theme. A
literal colour in feature code is a review finding.
- Any new state indicator needs a non-colour encoding, normally the filled or
hollow mark, so it survives greyscale rendering.
- Screenshot evidence is stronger here than a colour description, so the
reviewed surfaces are captured in `docs/design/monochrome/`.
- A dark theme becomes a token-level change instead of an app-wide rewrite.
- Platform launch screens and app icons keep their current assets and are out
of scope for this record.

## Follow-up controls

- Review new UI for token use and for a non-colour encoding of any new state.
- Re-capture the reference screenshots when a reviewed surface changes shape.
- Verify contrast for secondary text on ink and on paper when the grey ramp
changes.
13 changes: 7 additions & 6 deletions docs/architecture/adr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ Architecture decision records (ADRs) capture durable decisions and their
consequences. Accepted describes the agreed direction; it does not imply every
enforcement detail is already implemented.

| ADR | Status | Decision |
| --------------------------------------- | -------- | --------------------------------------------------------------------------------------- |
| [0001](0001-package-boundaries.md) | Accepted | Separate domain, BLE transport, vendor protocol, platform adapter, and app composition |
| [0002](0002-local-first-health-data.md) | Accepted | Keep health data local by default and make movement explicit |
| [0003](0003-platform-release-model.md) | Accepted | Build source-bound mobile artifacts and release only through fail-closed platform lanes |
| [0004](0004-app-localization.md) | Accepted | Use a user-controlled English/Simplified Chinese language policy across app and live UI |
| ADR | Status | Decision |
| ---------------------------------------- | -------- | --------------------------------------------------------------------------------------- |
| [0001](0001-package-boundaries.md) | Accepted | Separate domain, BLE transport, vendor protocol, platform adapter, and app composition |
| [0002](0002-local-first-health-data.md) | Accepted | Keep health data local by default and make movement explicit |
| [0003](0003-platform-release-model.md) | Accepted | Build source-bound mobile artifacts and release only through fail-closed platform lanes |
| [0004](0004-app-localization.md) | Accepted | Use a user-controlled English/Simplified Chinese language policy across app and live UI |
| [0005](0005-monochrome-design-system.md) | Proposed | Carry glucose state with contrast, weight, and shape in one monochrome token set |

## Adding an ADR

Expand Down
Binary file added docs/design/monochrome/01-onboarding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/design/monochrome/02-target-range.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/design/monochrome/03-dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/design/monochrome/05-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/design/monochrome/06-sensor-lifecycle.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions docs/design/monochrome/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Monochrome design reference

Screenshot evidence for
[ADR 0005](../../architecture/adr/0005-monochrome-design-system.md). Captured
from the deterministic demo driver in a release web build at a 430x932
viewport, so the readings are simulated and no sensor or health data appears.

Re-capture these when a reviewed surface changes shape.

| Screen | Shows |
| -------------------------------------------------- | -------------------------------------------------------------- |
| [Onboarding](01-onboarding.png) | Ink medallion, type scale, and the paper background |
| [Target range](02-target-range.png) | Inset panel, ink slider, and tabular figures |
| [Dashboard](03-dashboard.png) | Ink hero, drawn logo mark, stage pill, and the notice bar |
| [History and patterns](04-history-and-patterns.png) | Chart trace, target band, and the timeframe selector |
| [Settings](05-settings.png) | Grouped list rows, section labels, and the inverted mark |
| [Sensor lifecycle](06-sensor-lifecycle.png) | Life ring, status pill, and the label and value pairing |
Loading
0