Weight, size, colour, and when a glyph may stand alone.
Part of the Konjo design language. The laws in the spine apply here unless this chapter contradicts them.
In the mobile app, every icon comes from
src/components/Icon.tsx, which wraps Phosphor. No ad-hoc
imports from phosphor-react-native, no SVG pasted into a component, no emoji.
Studio uses Lucide (the dialect), and this chapter's rules split
accordingly. The sizes (iconSize 16 inline / 19 status / 24 standalone), the colour rules, the
one-glyph-per-tile budget and the never-decorative rule are set-independent and apply to both.
The weight system below is Phosphor's — regular and fill, where fill is a state and
never emphasis — and Lucide has no weights: a Studio icon is a single stroke, and a Studio
"filled" state is carried by the control around the glyph, not by the glyph. Studio has no
Icon wrapper of its own, so its imports are direct and its discipline is convention rather
than a chokepoint. This paragraph exists because the sentence above it said "every icon" and
was false for a third of the product. The wrapper exists so the set stays finite and one name means one glyph
everywhere — the alternative is three different "add" icons on three tabs.
Need a glyph the wrapper does not export? Add it to the wrapper. That is a two-line change and it is the whole system working.
Weight
Phosphor ships six weights. Konjo uses two, and the wrapper already picks between them:
weight ?? (active ? 'fill' : 'regular').
| Weight | When |
|---|---|
regular |
Everything. The default, and correct unless the glyph is showing state. |
fill |
The selected tab, the active filter, a completed step, a liked post. |
fill is a state, not emphasis. Filling an icon to make it look important is the same
mistake as making a heading red — it spends a budget on decoration. thin, light, bold
and duotone do not appear in Konjo; mixing weights across one screen reads as two icon sets.
Size
Three sizes, from the iconSize scale:
| Size | Use |
|---|---|
inline |
Sitting in a line of text — a 16pt glyph beside a 15pt label. Optically matched to the type, never larger. |
status |
A status glyph on a tile or row. Small enough to stay a marker, big enough to identify. |
control |
Standing alone as a tappable thing: header actions, tab bar, an icon-only button. Always inside a 44pt target. |
Nothing between. A glyph that needs to be bigger than control is not an icon, it is
illustration — see imagery.
Colour
text.primaryby default. An icon is content.text.tertiaryfor a chevron or other pure affordance — it is furniture, and it is card-only (on the tinted page usetext.secondary).- Never
text.quaternaryfor anything meaningful. It is legal only for a genuinely disabled glyph or an unfilled track. - Red only if the icon is the screen's one red role. A red glyph plus a red button is two roles and one has to give. See L4.
- On a hero block,
text.onHero— never a hardcoded hex.
An icon carrying meaning is non-text content: it needs 3:1 against its background (SC 1.4.11), which is why a status glyph sits bare on the tile rather than inside a tinted chip at 1.14:1.
Icon-only controls
An icon alone is legible when all three hold:
- It is a platform convention — back, close, search, share, add, more.
- It sits in chrome, where people expect symbols.
- It carries an
accessibilityLabelsaying what it does.
Otherwise it takes a label. A glyph you invented for "reconcile attendance" teaches nobody, and the person who needed it most is the one who will not tap an unfamiliar square.
Never an icon and a label that say different things. If the label is "Log a session", the icon is not a stopwatch because stopwatches look nice.
Icon plus label
- Icon leads, label follows,
spacing.tightbetween them. - Optically centred on the text baseline, not the box.
- One icon per label. A row with a leading glyph, a trailing chevron and a status marker is already at its limit.
Never
- A glyph used as decoration next to a heading.
- Two icons meaning the same thing in one feature.
- An icon substituting for an empty state.
- A brand logo used as an icon.
- Emoji anywhere in chrome. See voice.