Provider status — dot & glyph vocabulary

LLM Settings tab · one short design decision · rendered at native width (260pt sidebar), SF font, system colours.

The status indicator next to each provider is a 10 pt coloured dot. After this branch it carries three colour meanings on two hues: green = online, amber = unavailable (429/offline/5xx) and amber = out of credit (402), red = invalid. The two ambers are different states sharing one dot; green-vs-amber is the whole “is it ready” signal carried by hue alone. That’s the question.

The a11y floor (gruber)

HIG: “differentiate without colour — add shape or glyph.” Green/amber and a deuteranope can’t tell the dots apart. Pair each coloured indicator with a shape, not just hue.

Parsimony (William)

Glyph only the exceptions (the ambers + red); leave .online a plain dot. The normal case stays silent.

The tension (your rule)

“Absence is information — no glyph for the normal case.” gruber’s fuller set puts a checkmark on .online too. That’s the line to draw. The settling indicator (G) is the same vocabulary.

The states, with example data

StateDotWhenLabelActivatable?
.online2xx — key valid & reachableOnline · Last verified 2 minutes agoyes
.outOfCredit402 — authenticated, no creditOut of credityes (top up & run)
.unavailable429 / 5xx / offline (transient)Unavailableyes
.invalid401 / 403 — key rejectedInvalid keyno
.notSetUpno key in KeychainNot set upno
.checkingfirst validation in flightChecking…no

Two ambers, one hue. In the table you read them apart by the label — but the column-scan signal is the dot, and that’s where colour-only fails.

Three treatments, same data, native width

A · Colour only (today)
Ships today. The two ambers and green/amber are hue-only. Fails the a11y floor.
B · Glyph the exceptions
Online stays a silent plain dot (honours “no glyph for the normal case”). The two ambers now differ by shape; red is unmistakable. Empty slot reads as a hollow ring.
C · Glyph every state
Every state shapes-up, incl. a checkmark on .online. Most a11y-redundant — but the checkmark on the normal case is exactly what “absence is information” argues against.

Why colour-only fails — the same dots, three ways

Left: normal vision. Middle: greyscale (luminance only). Right: deuteranopia (red-green, ~6% of men). Watch A’s green/amber/amber/red collapse; B keeps every state distinct by shape.

A · colour only

normal online credit unavail invalid
greyscale
deuteranopia

B · glyph the exceptions

normal online $credit unavail invalid
greyscale $
deuteranopia $

The settling indicator (G) — same vocabulary question

During the eager board’s silent background reconfirm, a row keeps showing its cached value. Should a reconfirming row look different from a settled one? If yes, that’s another glyph in the same family. Here Claude is mid-reconfirm (faint pulsing ring behind the cached green dot) — gates nothing, just “the app is checking.”

Settled vs settling
vs the alternative: reconfirm in total silence (no settling cue) and only move the dot if the verdict changes.

The decision

Three questions, in order:

  1. Shape the exception states? (B) — amber-credit, amber-unavailable, red-invalid each get a distinct shape. This clears the a11y floor and disambiguates the two ambers. My read: yes — it’s an Apple-documented floor and the two-amber collision is real.
  2. Glyph .online too? (C) — a checkmark on the normal case. This is the one that collides with “absence is information — no glyph for the normal case.” B leaves it a plain green dot; C marks it.
  3. Show a settling cue during reconfirm? (G) — or reconfirm invisibly. Additive, gates nothing; or silence if the dot only moves on a real change.

Glyphs shown are stand-ins (HTML can’t use SF Symbols). In the app: exclamationmark.triangle.fill (unavailable), creditcard.trianglebadge.exclamationmark or dollarsign.circle.fill (out of credit), xmark.octagon.fill (invalid), checkmark.circle.fill (online, if C). Provider icons are letter placeholders — real app uses the monochrome brand logos.