Foundations
Colors
Components never use a raw colour. They use a semantic token, and the theme decides what that token resolves to. Dark is the reference theme; light is designed separately rather than inverted.
Surfaces
Depth in Luc UI is a luminance step plus a hairline, not a big drop shadow. Surfaces form an ordered stack.
Text
Four text levels keep hierarchy predictable. Anything below 4.5:1 against its surface is only ever used for decorative microcopy.
text.primaryTitles, values, active labels
text.secondaryBody copy, descriptions
text.mutedMeta, captions, axis labels
text.disabledDisabled controls and placeholders only — never body copy
text-accentAccent
One accent. It marks selection, focus and action — nothing else.
Accent in context
Primary action, soft selection, and accent text.
Status
Status colour always ships with a label or a glyph. Colour is never the only carrier of meaning.
Borders and lines
Hairlines carry most of the structure. They are always alpha-based so they sit correctly on any surface.
Rules
Do
- Use
bg-surface-*andtext-fg-*utilities. - Add a new token to
tokens.csswhen you need a new role. - Check contrast in both themes before shipping a new pairing.
Don't
- Hard-code hex,
rgb()or palette scales inside a component. - Reach for a second accent colour for “variety”.
- Put the accent behind body text.