Colour token naming is simpler than you think
Most colour token systems break in the same places. Abbreviated names, values baked into the token name, mixed casing, semantic meaning crammed into the primitive layer. None of it is necessary. The conventions that work are short and consistent.
Use full colour family names in kebab-case. orange-400, not org-400 or Orange400 or clr-o-4. The name should be self-explanatory without a reference table. If a developer has to look up what clr-o-4 means, the name is doing negative work.
Never include colour values in the name. orange-400 is correct. orange-ff6b35 is not. The hex value will change if the colour is refined, and the token name will be wrong from that point forward. Names describe position and identity, not value.
The number encodes perceptual lightness position, not importance or order. 50 is lightest, 950 is darkest. That's the only thing the number means at the primitive layer. orange-400 is lighter than orange-600. Immediately legible without opening Figma.
Keep primitive and semantic tokens strictly separate. Primitive tokens describe what a colour is: orange-400. Semantic tokens describe what it does: color-action-primary. Components reference semantic tokens. Semantic tokens reference primitives. Updating the brand colour means changing one assignment at the semantic layer. Nothing in the component code changes.
The system breaks when these layers merge. A token named button-primary-orange is doing both jobs badly. Too specific to be a primitive, too vague to be a useful semantic alias.
→ The rules: Full names, kebab-case, no values, numbers for lightness, two layers kept separate. Everything else follows from those five rules.