Skip to main content

Typography

One row per role in semantic.type, rendered in the actual style. Every value is read from the token file; the specimen itself is rendered with the generated .modulus-type-* class, so what you see is the same CSS a component gets.

Which font is actually rendering

Stated first because it has already caught one real bug: the token file names the text family Inter, but @fontsource-variable/inter registers its face as Inter Variable, so the plain name alone never reached the bundled file and body text silently rendered in system-ui. document.fonts.check() is no use for this — it returns true for a family the browser merely falls back to. The table below instead matches each role’s computed font stack against the families that really have a registered @font-face, and reports the first one that does.

Roles

The three -mobile roles are not separate rows. Figma has no media queries, so they exist in the file as separate tokens; here each merges with its desktop counterpart into one responsive role, showing both values and the breakpoint where it switches. Resize the preview to see the specimen change.

Families

Primitive scales

Roles reference these; components should use the roles.

Notes carried from the token file

Line heights are absolute pixels so every role lands on a whole pixel and, above 20, on the 4 grid. Letter spacing is em, which CSS takes directly — Figma expresses it as a percentage, so multiply by 100 when authoring a Figma text style by hand. Text styles are not variables, so the importer never touches them and they must be updated manually.