Capitalisation
Nothing in this product is set in capitals — not a heading, not a label, not a badge.
Never set text in all capitals. Not a section heading, not a table header, not a badge, not a chart legend, not a button. There is no case where it is the right answer here, so there is no exception to weigh up.
It applies to both ways of doing it:
- The
uppercaseclass, and any othertext-transform: uppercase. 244 of them came out of the app in one pass, across the web app, admin, the docs site and@statshub/ui-web. toUpperCase()on text that is rendered. A team's short name wasteamName.substring(0, 3).toUpperCase()in a dozen places; it issubstring(0, 3)now, and reads "Ars" rather than "ARS".
What is not covered
Acronyms and codes keep their capitals, because the capitals are the term
rather than a style: BTTS, SOT, GK, H2H, O/U, AGS, xG, a locale's
EN. Writing "Btts" would be wrong in a way that has nothing to do with
shouting.
toUpperCase() for matching is untouched. positionSortOrder[position.toUpperCase()]
and SUB_OFF_BY_CODE[position.toUpperCase()] normalise a key before a lookup —
nobody reads the result, and removing them breaks the lookup. The rule is about
what reaches the screen.
Data is data. A league called NWSL and a club called PAOK arrive from
the API in capitals and stay that way. If that ever needs changing it is a
question for the ingest, not for a stylesheet.
Keeping it out
bun run check:caps in apps/statshub-web fails if the class comes back. It is
part of lint, so it runs in the same gate as everything else — a rule with no
gate is a rule that lasts until the next component.

