ADR-0015: The design system is the only visual source — never hand-roll

  • Status: Accepted
  • Date: 2026-06-05
  • Scope: core (any app with a deliberate visual identity)

Context

Inventing colors, spacing, radii, or atom shapes “by feel” produces drift and
an off-brand, inconsistent product — one plausible-looking hand-rolled
component at a time. The Expenses admin console learned this the hard way and
adopted the rule first (its docs/expenses/frontend-admin/ ADR records the
app-specific mechanics).

Decision

  • Each app has a design-system skill as its visual source of truth (tokens,
    type scale, atom CSS, screen patterns), mirrored into the app’s
    src/styles/theme.ts (0014-theme-tokens-not-hex). Do not invent
    visual primitives outside it.
  • When the system doesn’t cover a need:
    1. Extend its existing patterns — open the skill, follow the established
      tokens/atoms.
    2. For a genuinely new primitive, prototype first (prompted-prototype
      flow in a design tool), get approval, then port — never write speculative
      atoms by feel.
  • Design ≠ backend. Design mocks may show features the backend doesn’t
    expose; when porting a screen, verify every backend-calling element has a
    real endpoint and strip what doesn’t (no disabled “coming soon”
    affordances).
  • Apps’ design systems don’t mix. A customer app and its admin console can
    (deliberately) have distinct visual identities — pull from the right one.

Consequences

  • Visual consistency survives velocity; “looks close enough” stops being a
    merge-able argument.
  • Slightly slower than free-styling (consult the system first) — the cost of a
    coherent product.
  • 0014-theme-tokens-not-hex — the token discipline this feeds
  • Project instances: docs/expenses/frontend-admin/0002-never-hand-roll-the-visual-layer.md
    (origin of the rule; admin-specific mechanics)