# Styles

Write the text and effect styles into your Figma file with the Mirror Styles plugin, and keep them bound to the variables.

Figma variables hold single values, so the composite typography tokens and
the shadows reach Figma as styles instead: a text style applies a family,
weight, size, line height and letter spacing in one click, and an effect
style holds a shadow. Both are written by Mirror Styles, the plugin we ship,
whose one input is the `styles.json` the export writes. It makes no network
requests; everything it needs is in that file.

Everything below describes the styles built from our standard token set. A
token set of your own changes where the text styles resolve from, and
[Custom Tokens](/figma/custom-tokens) covers that.

## Generating the payload

```bash
pnpm mirror tokens
pnpm mirror figma
```

`mirror tokens` compiles the token source into `.maas/tokens/`, and
`mirror figma` reads that compiled output, so the two run in this order. The
export is written to `.maas/figma/`: the variable mode files, which
[Variables](/figma/variables) covers, and `styles.json` beside them. The
text styles resolve from a typography file `mirror tokens` copies out of the
token source alongside the compiled tokens; if your token source has no such
file, set `figma.typography` to `false` in `mirror.config.ts` and the export
skips text styles.

## Bindings

Import the typography collection before the first plugin run. The text styles
do not copy their values: family, weight and size are bound to the typography
variables, along with any letter spacing authored as an absolute length, so a
bound style re-resolves through the collection’s modes, and a frame set to
the small-screen mode renders every style at the small-screen scale with no
second set of styles anywhere. Line height and the percentage letter spacings
are written into the style as plain percentages, and a percent stays correct
relative to whatever size the bound variable resolves to.

## Running the plugin

Run the plugin and select or drop `styles.json`. It reads the document’s
local styles and variables once and compares them against the payload before
writing anything. A style the payload names and the file lacks is created, a
style whose values or bindings drifted is updated with every binding
re-asserted, and a style that already matches is left alone. Matching is by
name within each kind, and the plugin sees local styles only, so a style
subscribed from a team library is neither matched nor reported.

Two situations make the plugin skip a style rather than write it. A font
Figma does not have available skips the style, and the report names the
family and face, so either install the font or map the token’s family to one
you have through `figma.fonts` in `mirror.config.ts`. A binding that names a
variable the document lacks skips the style too, and the report says which
collection to import first; writing raw values instead would produce a style
that looks right and stops updating.

## The report

The report separates a write from a no-op. It counts created, updated,
unchanged and skipped styles, for text and effect styles separately.
Duplicated style names are listed too (the first copy in the document is
updated, the rest are left alone), and so are styles that sit under the
payload’s folders but are no longer in the payload. Nothing on that last
list is touched, and the plugin never renames a style or touches a variable,
a collection or a node. Removing a style, like removing an orphaned
variable, is done by hand in Figma.

## What a re-run changes

Because the text styles are bound to the variables, a value-only token change
never needs the plugin. Updating the affected modes through Figma’s Import
mode is enough, since the styles resolve their values through the collection.
The plugin runs when the set of styles itself changes, a role added, renamed
or rebound, which is visible in the diff of `styles.json`.

::docs-table
---
columns:
  - label: Change
  - label: What to do
rows:
  - items:
      - label: A style was added, renamed or rebound
        plaintext: true
      - label: Run both commands, then run the plugin on styles.json. If the style binds new variables, re-import the typography modes first.
        plaintext: true
  - items:
      - label: A style was removed
        plaintext: true
      - label: Nothing is removed in Figma. The report lists the style; delete it by hand.
        plaintext: true
---
::

## Further reading

- [Variables](/figma/variables): the mode files, the import mechanics and the
  naming rules.
- [Custom Tokens](/figma/custom-tokens): text styles resolved from a
  typography file of your own.
- [CLI](/overview/cli#mirror-figma): the command, and the arguments the build
  commands share.
