Docs
Most documentation in Grails hangs off something synced from Figma: a component, a token collection, a text style. That covers “how do I use this button” well, and covers nothing else. A design system also needs the writing that belongs to no single component — voice and tone, how to name things, when to break a rule, what your accessibility floor is.
The Docs section is where that writing lives. A page is documentation you create and own: it does not appear because a sync found it, and it does not disappear when someone deletes a component in Figma.
Overview
Docs is accessible from the Knowledge dropdown menu in the top bar (alongside Patterns). It has a panel on the left that stays with you on every Docs page, and the page you are reading in the centre. The panel does not reload as you move between pages, so whatever you opened, searched or filtered in it is still there when you come back to it.
At the top of the panel, Overview opens the section’s front page: what changed in your documentation, newest first. Below it, two tabs:
- Design system — your components, token collections and styles, each with its documentation status. Components appear exactly as the Components section lists them: sets and standalone components, in the same folders. Clicking a component, a token collection or a style opens its page. A token collection is one entry whether it lives in Figma, in your code or in both (see Token collections in code below). A token has a page too, but not a row in the panel: you reach it from its collection’s page (see A token’s page below).
- Pages — the pages your team writes, grouped by folder. This is what the section adds.
What the dots mean
Each component, token collection and style carries a dot, and the legend under the tree repeats what each one means:
- Filled green — Guidelines written. Someone documented it.
- Hollow — Anatomy only. Nothing written yet. Every synced component starts with its anatomy, so it is never truly empty; a token collection or a style with a hollow dot has nothing written at all.
- Amber — Out of date after a sync. Something was written, and a sync has changed the entity since.
Finding something
The search box at the top of the panel narrows both tabs by name as you type. On the Design system tab, three filters sit under it:
- Type — only components, only token collections, or only styles.
- Status — only what is documented, only what is out of date, or only what has nothing written. Documented includes what went out of date: it has documentation, it just needs a look.
- Source — where a component or a token collection lives: Canonical (in Figma and in code), Design (only in Figma) or Code (only in code). A style has no counterpart in code, so choosing a source hides styles.
While you search or filter, every folder opens so nothing that matches stays hidden. Clear search and filters brings the whole tree back.
Code only components
Components that live only in code (uploaded from your repository with grails-cli sync, without a matching Figma component) are listed at the end of the components list in a dedicated Code only folder, marked with the code icon. Inside this folder, components are organized by the folder of their file in the repository (without leading src/).
Each component’s page has one address by its canon ID (/docs/components/[canonicalId]), whether you came from Figma or code. Older links still open it.
Token collections in code
Token collections work the same way, with the same marks:
- One entry per collection, whichever source it comes from. A collection that lives in Figma and in your code (once the two are matched) is one row with both source marks lit. One that lives only in code shows the code mark alone and sits in a Code only folder at the end of the Tokens group; the folder opens by itself when you are on one of its collections. One that lives only in Figma has no mark, because Figma is where this list comes from.
- Only collections that exist now are listed. A collection deleted in Figma, or that your repository no longer declares, is not in the panel. If its code side is still there, it stays as a collection only in code. A link to a deleted collection still opens its page.
- One address per collection, by its canon ID (
/docs/token-collection/[canonicalId]). Older links — the one that used the Figma collection’s own ID, or the code collection’s — open the same page, and they keep what the link carried (the side, the view, the format).
Floating or docked
The panel can float over the edge of the page as a card, as tall as what it holds, or be docked to the side at full height. Choose which in User Settings → Appearance → Side panels; the choice applies to both panels.
On a phone the panel opens from the button at the foot of the screen, and closes by itself when you pick something in it.
The Overview
Overview lists what changed in this project’s documentation, newest first: pages created or deleted, and documentation added, edited or removed on a component, a token collection or a style. Changes of the same kind made by the same person within a few minutes are grouped into one line.
Search the list, or narrow it with Filter (by kind of change) and Author. Load older activity goes further back.
A page the list names is a link to it, unless the page has been deleted: Voice and Tone in a line about creating a page, or in one about documentation written on a page, opens that page. A deleted page stays as plain text.
The bar at the bottom of the Overview has Create Doc page, for admins and editors.
Renaming a page or moving it to another folder does not appear: those changes are not recorded yet.
If the list cannot be read, the Overview says so and offers to try again, rather than showing an empty list.
A component’s page
Clicking a component in the panel opens its page. At the top are its name, its sync status, how many variants and properties it has (a single component shows its properties and layers instead), when it was last synced, and its description from Figma when it has one. The line beside the name ends with the name of the component’s Figma file, as a link that opens the file when Grails can build one, and a Snowflake chip follows the sync status when the component lives in a Figma file that is not a library. When the file’s name is not known, nothing is added. The Anatomy tab shows what the component is made of, read from its latest sync; Docs holds its documentation, and Graph shows what a change to it would affect.

Design, Code, and Both
For a component that lives in both Figma and code, the header of the Anatomy tab includes a three-way switch: Design, Code, and Both. (A component that exists in only one source shows its anatomy directly).
- Design: The component’s anatomy as captured from Figma: the preview, which is the Figma Screenshot or a Schematic drawn from the spec, layer markers, interactive measurements, and design token bindings described below.
- Code: The component’s anatomy as parsed from its source code:
- Schematic instead of an image: Code does not render an image, so the Schematic section draws the component from its spec: layout, sizes (including minimum and maximum width and height), padding, gap, corner radius, colours and text, with every token at its value in the mode you picked (see Modes in The bar at the bottom). Its bar has the same tools as the Design preview (see The preview). A slot the code declares, such as
children, is drawn as a dashed box with its name. What the drawing could not show is named under it, with the reason, as it is for Design. - Elements: Numbered in source order, displaying the element key, type (or
Instance of <Component>), and declaration file with line number (file:line). - Layout: Direction, padding, gap, width, height, and corner radius as declared in code. Raw literal values not bound to tokens are underlined with dashes (hardcoded).
- Properties: The props declared by the component in code, with type, accepted values, and default.
- Tokens & Hardcoded: The tokens the code uses, grouped by category, with resolved values, swatches, and usage locations; followed by the Hardcoded section listing literals that a token could have held.
- Variants: If the code defines variant axes, chips allow picking any combination to inspect that variant’s overrides.
- The panel on the right: Pick an element on the schematic or in Elements and the panel describes it with the same inspector as Design: its text, its layout with the padding drawn as a box, its colours, stroke and radius, and its position. A token shows as its chip, the same chip as in Design: a colour token shows its colour before its name, and the value as your code writes it (an
oklch(), for example) is in the chip’s tooltip and in the token’s panel. A hardcoded value is dashed. - The bar at the bottom: The configuration picker, Modes, and More: Copy link to this view, and Open in repository when Grails can build a link to the component’s file.
- Empty states: If the scanner has not read the component yet, the tab explains: «No anatomy yet: it appears once the scanner reads this component’s file.» If the spec contains only AST structure without styling, a note warns: «This spec records the structure only: the scanner read no spacing, colour or typography from this file.»
- Schematic instead of an image: Code does not render an image, so the Schematic section draws the component from its spec: layout, sizes (including minimum and maximum width and height), padding, gap, corner radius, colours and text, with every token at its value in the mode you picked (see Modes in The bar at the bottom). Its bar has the same tools as the Design preview (see The preview). A slot the code declares, such as
- Both: Places the Design and Code schematics side by side, and under them two tables whose rows are joined by wires wherever they are the same thing in Figma and in code. See Both: Design and Code side by side below.
The Anatomy tab is made of these parts, from the top, and each one answers a question:
| Part | What it tells you |
|---|---|
| Variants | Which combinations of the set’s properties exist, and what each one looks like |
| Overview | The variant on screen, as the Figma image or as a schematic, with a number on each element and its measurements |
| Elements | What the component is made of: each element, what it is, and when it shows |
| Layout | How each container arranges what it holds: direction, padding, gap, size and corner radius |
| Properties | What a designer can change on an instance, and what each property controls |
| Tokens | Which tokens the variant uses, where it uses each one, and their values in each mode |
| The panel on the right | One element in detail (Props), or every element as a tree (Layout) |
| The bar at the bottom | The variant on screen, Compare, Modes, Export and More |
A single component has no Variants: its tab starts at Overview.
Variants
A component set opens on its variants, laid out the way Figma lays out the set: one property down the side and another across the top, each cell showing that variant’s image. A cell with a dash is a combination the set does not have, and it cannot be picked.
- The properties that do not fit in the grid appear above it as rows of values. A value with a dashed border has no variant together with the current values of the other properties; picking it moves them to a combination that exists.
- Click a cell to see that variant. Everything below it, and the panel on the right, then describe the variant you picked.
- See it in Figma. The bar above the grid switches between Grails, the grid, and Figma, the component live in Figma. To see it you need to be able to open the file in Figma, through your session or because the file is shared by link. When Grails does not know the component’s Figma file yet, it says so and asks you to sync the file again with the plugin. On a phone the bar does not offer it.
- Compare it with another variant. Nothing is compared until you ask for it: Compare, in the bar at the bottom, picks the variant to compare with. The variant on screen is then A and the one you picked is B, both marked in the grid, and under the grid What changes from A to B lists the differences — a size, a colour, an element that only one of them has — and past eight, says how many more there are.


The preview
Overview, under the variants of a set and at the top of a single component’s tab, shows the variant on screen. The switch at the start of the bar above it chooses the view:
- Screenshot — the image as Figma rendered it. The tab opens on it.
- Schematic — the component drawn from its spec instead: layout, sizes (including minimum and maximum width and height), padding, gap, corner radius, fills, strokes and text, with every token at its value in the mode picked in Modes (see The bar at the bottom). It draws only the elements the variant on screen shows with the configuration you set, so picking another variant, or turning a true/false property off in Properties, redraws it.
On a large, tall screen the preview stays in view while you scroll through the tables under it, so picking an element or switching a property answers in place.
The bar also holds the preview’s tools, and they work on both views:
- Markers — a number on each element, the same numbers as the Elements table. Click one, or click the element on the image, to pick it: the tables and the panel on the right follow.
- Spacing — for the element you picked, its padding and the gaps between its children, drawn over the image, with each side of the padding labelled with its value, or one label when all four match; for anything else, its distance to each edge of the element around it.
- Measure — point at another element to see the distance between them. Holding Alt does the same without turning the tool on.
- Canvas background — follow the theme, light, dark, or a transparency grid. An image with a transparent background shows the canvas through it, so a dark element can disappear on a dark canvas; the grid of variants uses the same background.
- Zoom — fit, or step between 75% and 300%.
Over the screenshot, markers and measurements come from where Figma placed each element, and they are drawn only over the image they were measured on. Markers and measurements are computed from Figma layer coordinates. If a component is missing position data or requires higher visual fidelity, re-syncing the component from the Figma plugin refreshes its markers and bounding dimensions. Over the schematic they come from the drawing itself.
Under the schematic, a line names what it could not draw and why, so a gap in the drawing is never a mystery. There is one line per reason:
- Not drawn: Button gap — their token is not synced with Grails. Sync the library it comes from to draw them.
- Not drawn: Label fill — Grails cannot tell which token they use.
- Not drawn: Icon fill — their value is not one the drawing can use.
A property set with a variable that is not synced with Grails is drawn with the value Figma gives it, when Grails has that value, and the panel on the right shows it on the token’s chip. A solid color style is drawn with Figma’s value, synced or not, when the spec carries that value. That value is the one in Figma’s mode, so it does not change with the mode you pick. A component synced before Grails kept these values gets them when it is synced again from the Figma plugin; until then, the line above names the property.
A spec that records no elements to draw says so in place of the drawing: The spec records no elements to draw.

Elements
Every element of the component, numbered in reading order, with what it is and when it shows:
- Required — always there.
- Optional — a property shows or hides it; the property is named next to it, with whether it starts shown or hidden.
- In some variants — some variants have it and others do not. When the variant on screen does not, the row says so and is dimmed.
- Hidden — present, and hidden in every variant.
- Unknown — see the note below.
An instance of another component shows that component’s name. When your project has that component synced, the name links to its page; a dashed name means the component comes from a library this project has not synced.
In a component set, a switch on the right of the section’s title chooses which elements the table lists: All elements (the default) lists every element of the component, with the ones the variant on screen does not show dimmed and the reason beside them, and This variant lists only the ones the variant on screen shows. A component without variants has no switch, because what it shows is all it has.

Layout
The auto layout of every container: direction, padding, gap, width and height with how each is decided (Hug, Fill or Fixed) and the limits Figma sets on them (min, max), and corner radius. Padding is written as short as it can be said: one value when all four sides match, a vertical and a horizontal value when they pair up, and the four sides otherwise.
A padding, gap or radius written as a plain number, with a dashed underline, is hardcoded: a token could have held it, and none does.
Lengths on the tab, in its tables, in the panel on the right and in the Markdown export, are written with at most two decimals.

Properties
What a designer can change on an instance, as Figma declares it: each property, its type, its default value and the element it controls. A variant property controls the whole component.
A true/false property whose element the component records has a switch. Turning it off marks that element as hidden in the Elements table and in the Markdown export, so you can see the component without it.
The default of a slot property is a component, and it appears as that component’s name. When your project has the component synced, the name links to its page; otherwise it appears dashed, as in Elements.

Tokens
Every token the variant on screen uses, grouped by what it is (spacing and size, colour, typography, effects), with the places it is used and its value in each mode when the modes differ. Click a token to open it: a variable opens in its panel, and a text style in the typography panel. A colour, effect or grid style copies its name instead, since it has no panel of its own. A token that is not synced with Grails says so, and offers to copy its name. When your project holds several Figma files, a token is looked up in the component’s own file first; if two other files have it and the component’s does not, the chip says Grails cannot tell which one it is, rather than picking one. The same goes for the tokens in the panel on the right. Values that are hardcoded appear apart, at the end.
In a component set whose colours change from one variant to another, the section says how many colour tokens its variants use between them.

The panel on the right
The panel on the right has two views:
- Props — the element you picked: where it sits, the component it is if it is an instance, its text, its layout with its padding drawn as a box (a size that hugs or fills says so), its fill, stroke and radius, its position (its offset from the component’s corner, and its distance to each edge of the element around it; an element that is not drawn has none), and when it shows. Copy tokens copies the names of the tokens it uses, one per line, and Copy spec copies its specification as JSON.
- Layout — every element as a tree, with the same numbers as the tables. The tab says how many there are, and an element the variant on screen does not draw stays in the tree, dimmed and marked. The tree follows the variant on screen: each element hangs from its parent in that variant, in the order the variant lays them out.
With nothing picked, Props describes the component itself: its size, direction, gap, alignment, padding, fill and radius.
Token values in the panel are shown in the mode picked in Modes.
Pick an element from any table, or from the tree, to inspect it. Picking in a table opens Props; picking in the tree keeps you in Layout, so you can go through the tree one element at a time.



It is the section’s right panel, and it behaves like the left one: it floats over the edge of the page or is docked to the side, as User Settings → Appearance → Side panels says. It stays on all three of the page’s tabs, so switching tabs moves nothing: on Docs it is On this page, on Graph it is the map’s own Inspector (see The Graph tab below), and before the component’s first sync it is the Inspector, with nothing to inspect yet. On a phone both panels open from the same bar at the foot of the screen.
The bar at the bottom
A bar floats at the bottom of the Anatomy tab, so its tools are at hand wherever you have scrolled to:
-
The variant on screen. In a component set, the bar names it; click it to change any property without going back to the grid. Values with a dashed border work as they do above the grid. The picker also says how many of the combinations the set could have actually exist. A single component shows Configuration instead, with a switch for each true/false property whose element it records (the same switches as the Properties table), or No variants when it has none.
-
Compare, in a component set, picks a variant to compare the one on screen with, from the same picker. While you compare, the bar marks the variant on screen A and the one you picked B, and adds two tools:
- ✕ stops comparing.
- Only what changes trims every section of the tab to what differs from A to B, shows each change as A → B, and says how much stays the same. It is off when A and B are the same variant, because there is nothing to compare.
In the Compare picker, Swap A and B puts B on screen and compares it with A.
-
Modes says, in a few words, the mode each token collection is read in (colors Light · theme Dark); click it to change them. It lists the collections the component’s tokens come from, with how many of the component’s tokens each holds, and a choice of mode for each one. It lists only the collections that have more than one mode, and the bar leaves Modes out when there are none. The schematic and the panel on the right show every token at its value in the mode picked for its collection, and in the collection’s default mode when you have picked none. A collection that declares no default mode says so (No default declared: it opens in its first mode in Figma.).
-
Export (the arrow down):
- Copy spec copies the specification of the element you picked, as JSON, like the button in the panel on the right. With nothing picked, it copies the component’s own.
- Markdown saves the Elements, Layout, Properties and Tokens tables of the variant on screen as a Markdown file, ready to paste into a pull request, a wiki or a ticket. Every name is written as it is in Figma.
- PNG saves the tab as an image, as you see it: the image with its markers, and the tables.
-
More (⋯):
- Copy link to this view copies the page’s address, with the variant on screen and the element you picked.
- Open in Figma opens the component in its Figma file. It is in the menu only when Grails knows the real key of the component’s file: without it, the item is not in the menu.
The preview’s own tools stay in the bar above the preview, next to what they change. On a phone, this bar is the one that also opens the two panels. On the Docs tab, the bar holds the documentation’s tools instead: see The Docs tab below. On the Graph tab it holds the map’s filters and tools: see The Graph tab.
![]()
Links to what you are looking at
The page’s address follows what you pick. Share it and the other person lands on the same variant (?v=Primary,Hover,Small) and the same element (#Label). If the set no longer has that variant, the link opens the default one.
Both: Design and Code side by side
Both is for a component that lives in Figma and in code. It answers two questions: is the code built the way the design says? and which part of the design is which part of the code? It draws both components the same way, lists their props and elements in two tables, and joins with a wire what is the same thing on each side.
The bar at the bottom picks what is compared: a Figma variant on the left and a code configuration on the right, each with the mark of its source and each followed by its own Modes when its tokens come from a collection with more than one mode (see The bar at the bottom). Matches, at the end, chooses which kinds of pair the tables show. Both has no Compare, Export or More.
The two schematics
Overview draws the Figma variant and the code configuration as schematics, side by side, each from its own spec and with the same numbered callouts as the Design preview. There is no Figma image: a render set against a drawing would show differences that are not in the specs. The preview’s tools (markers, spacing, measure, background and zoom) are shared by the two. Pick an element on either schematic and the other side shows its counterpart, when it has one. Each drawing names what it could not draw, as Design does.
Props and Elements, wired
Under the schematics, the Props / Elements switch chooses what the two tables list: Design on the left, Code on the right, and between them a wire for every pair of rows that are the same thing. The tables are always as tall as the longest list, so switching or picking never moves the page.
- Props lists the props each side declares, with their kind and how many values they have. A linked prop says linked; a linked prop that has values says N of M values, how many of its values are linked, and has a Link values button (see below).
- Elements lists each side’s elements, numbered as the callouts are, with what each one is: Component, Container, Instance, Slot, Text or Shape on the Design side, and its type, or Instance of …, on the Code side. A linked element says same, N properties differ, nothing to compare when no property is set on both sides, or not drawn here when one of the two is not in the variant or configuration on screen.
A wire says how much of the pair matches. A prop’s wire is green when all its values are linked, amber when some are, and red when none are; a prop with no values to pair, such as a true/false one, is green once linked. An element’s wire follows its properties (see Going into a pair): red when every property compared differs, amber when some do, and grey when there is nothing to compare. The Matches menu in the bar draws each kind of line beside its checkbox:
| Matches option | Line | What it means |
|---|---|---|
| Same token | Solid, in the colour of token chips | Both sides use tokens that are one token in Grails |
| Different tokens, same value | Dashed, in the colour of token chips | Two tokens that are not linked, with the same value |
| Same value | Solid green | The same value, or all of it matches |
| Same value, one tokenized | Dashed green | One side uses a token, the other a plain value, and they are the same |
| Partial match | Dashed amber | Part of it matches, or a value cannot be compared |
| Value drift | Solid red | None of it matches |
| Nothing to compare | Dashed grey | Two linked elements with no property set on both sides, or one of them not drawn here |
| Not linked | A dot | Rows with no counterpart |
Select all and Select none set every option at once. When some are off, the menu says how many are on (Matches · 5 of 8). A pair whose kind is off leaves both tables, and rows with no counterpart leave with Not linked. A row marked OK without a counterpart says OK in Design only or OK in Code only.
Admins and editors change the links; a viewer sees the wires and their states, without the controls:
- Link. Drag the dot at the edge of a row onto a row of the other side that has no link yet. A row with no link also has a Link button, which lists the other side’s rows with no link, for the keyboard and for a phone.
- Unlink. Point at a wire and click Unlink.
- Undo. Each change shows a message, Linked or Unlinked, with Undo. When Grails cannot save a change, the wire is not kept and a message says why.
When a component is synced, Grails also links by itself the two roots and the elements and props that have the same name on both sides, as long as no other candidate shares it. A pair you unlink is not linked again by itself at the next sync.
Link values
When you link two props that both have values, Link values opens on its own: a drawer with the two lists of values, linked the same way as the tables (drag, Link, or Unlink on a wire). Values with matching names are linked for you. Its title names the pair (size (Design) ↔ size (code)), and a line says Connect the values that match between the Design and Code. The prop’s wire turns solid green when every value on both sides is linked, and values left unlinked stay as drift to reconcile. Done closes it. You can open it again from a linked prop’s Link values button; a viewer sees Values instead and reads it only.
Going into a pair
On Elements, click a linked element’s row, or its wire, to go into the pair. The pair’s row goes to the top of each table, the other elements are dimmed, and the pair’s properties appear under it, wired property to property with the same lines: Height, Width, Padding ↔ and Padding ↕ (or each side apart, when a side uses a different token for each), Gap, Radius, Fill, Stroke, Text colour and Font size. Each property ends its row with its value: a token as its chip, at its value in the mode picked, a plain value as itself, and a colour with its swatch. A property only one side sets holds its place with a dash on the other side and has no wire, because an empty side is not a wrong one. A property set with a Figma token that is not synced with Grails is still listed, with the token dashed. When the token is a variable and Grails has the value Figma gives it, the row shows it, says in Figma, and compares it with the code’s value. Otherwise the row says not synced, and its wire is dashed, because there is nothing to compare. When two linked tokens have different values, the wire carries a ≠. Matches applies here too, and nothing can be linked or unlinked inside a pair. Picking a linked element on a schematic while Elements is showing does the same.
To come back out, click Back between the two tables’ titles (on a phone, the arrow). You can also click the side’s name in the table’s title (the breadcrumb reads Design › Label), the pair’s row or its wire again, or press Escape.
The panel on the right
The panel is always there in Both. With nothing picked it shows only its title, Inspector. Pick an element on either schematic, or a row in the tables, and it describes it: a Design tab and a Code tab, each with the element’s name, when the element has a counterpart, and only its own side when it has none. Each tab is the inspector of its source, as described above. Following the path in an inspector, to a parent or to a child, moves only the panel and not the tables. Escape lets go of the pick.
The summary
Under the tables (not while you are inside a pair), a summary counts Props and Elements together: N connected · N match · N in part, plus N nothing matches when there are any; N only in Design · N marked OK · N to review; and N only in Code · N marked OK.
Notes can appear above the tables. These two are not matched as one component, so there is nothing to link. appears when the Figma and code components are not matched as one component. The links could not be refreshed after the last sync; they may be behind. appears when the last sync could not update the links. When the links cannot be read, a red line says why; if the request did not reach Grails, it reads Could not reach Grails. Check your connection and try again.
The Docs tab
Docs is the component’s own documentation: what only your team knows about it, such as when to use it and how. It opens to read, the way a page does, and the bar at the bottom holds its tools:
- Edit opens the documentation for writing. Only admins and editors have it, on a screen at least 768 pixels wide: on a phone, documentation is for reading.
- History opens the component’s version history, once it has been synced.
- Import (the arrow up) adds documentation from a .md file, or from Markdown you paste: headings become Title blocks, tables become Table blocks, and the rest becomes Text. Before anything is added, it shows each block it will add and how many images, HTML fragments and footnotes it left out, since no block holds those. The blocks go at the end, the documentation opens for editing, and Save keeps them. Only admins and editors have it, on a screen at least 768 pixels wide.
- Export (the arrow down) saves the documentation as a Markdown file, or copies it as Markdown, with the component’s name as its title. A mention is written as the name of what it mentions. What you typed is written exactly as you typed it, and Text and Table blocks keep their formatting.
- More (⋯) holds Copy link to this view, which copies the page’s address, with the tab.

While you edit, each block is outlined and named, and the bar holds Add block, Save and Done:
- Add block lists the shapes the component can still take (some exist only once per component). The new block goes at the end, and the page scrolls to it. Title, Text and Table are written in place; every other shape opens its editor in a panel.
- Save writes every change at once and goes back to reading. It is off until there is something to save. If the save fails, the documentation stays open for editing, with your changes, and a message says why.
- Done goes back to reading without saving. With unsaved changes it asks first: Save, Discard changes, or Keep editing. Switching to the Anatomy tab asks the same, because the tab’s content goes when you leave it.
With nothing written, the tab says so and offers admins and editors Add block, Import Markdown, and, once the component has been synced, Start with Props from the spec: a Props block, whose editor lists the properties the component declares in Figma so you can describe each one. On a phone it offers none of them.
On this page, the panel on the right, lists the documentation’s Title blocks. Click one to scroll to its section; the one you are reading is highlighted. With no Title block, admins and editors are offered Add Title block, and a viewer reads No sections.

The Graph tab
Graph answers one question before you change a component: if I change this, what do I affect? It draws the component and, around it, only what uses it: the entities that depend on it directly, and the ones that depend on those. It never draws what the component itself uses; that is on the Anatomy tab.
The map is read when you open the tab and not before, so the other tabs and the other Docs pages never wait for it. A component that lives in Figma and in code is mapped once, from its Figma side; one that lives only in code is mapped from its code.

Reading the map
- The centre. The component sits at the left, outlined: it is the entity you would change.
- Levels. Each column to its right is a level, named above it. Direct holds what uses the component itself, Level 1 what uses something from Direct, and so on. An entity past the first level has a dashed ring around it. The map opens on the Direct level.
- Lines. A line joins an entity to the one it is reached through, and carries the words of the relation: used by (the entity uses the one before it), bound by (the entity has the token before it bound to one of its properties) or aliased by (a token that points at the token before it). Each relation has its own line, and a dotted line goes through a style. The bar at the bottom draws all of them.
- Shapes. A component is a rounded rectangle with a grid of four squares, a token a pill with a swatch (of its colour, when it is a colour) and a style a rectangle with Aa and a pattern a diamond. Under its name an entity says where it lives, and a component set says N of M variants: how many of the set’s variants the change reaches. A set counts once, however many of its variants are reached. Two small marks in the corner say whether it lives in Figma, in code or in both; a pattern has no marks, because it lives in neither.
- Picking. Click an entity and the map lights it, the entities next to it and the lines between them; the rest steps back.
To see further, click the + at the edge of an entity to open what uses it, and the − to close it again. Expand all and Collapse all, in the bar, open or close every level at once. Drag the map to move it and scroll to zoom, or use Fit, Zoom out and Zoom in. From the keyboard, Tab to an entity: Enter or Space picks it, E opens or closes it, and C centres the map on it.

The bar: filters and legend
The bar at the bottom of the Graph tab is where you narrow the map, and it is also its legend: each option draws the shape or the line it stands for, so there is no separate key to open.
| Control | What it does |
|---|---|
| Components, Tokens, Styles, Patterns | Show or hide a kind of entity. Each button draws the shape its entities have on the map, and is pressed while its kind is drawn. Patterns are the patterns that use the component, directly or through another pattern that contains it; they are drawn as diamonds, a draft says Draft under its name, and they carry no Figma or code marks. |
| Relations | A menu with one option per relation, each drawing its line: aliased by, bound by and used by. The button reads All relations, or N of 3 relations when you have turned some off. A note under the options shows the dotted line: through a style. |
| Expand all, Collapse all | Open or close every level, and fit the map to the screen. |
| Fit, Zoom out, Zoom in | Frame the whole map, or step the zoom. They wait until the map is on screen. |
There are no buttons to limit the levels: you reach a level by opening the entity before it, or all of them with Expand all.
The bar always fits the page. When the page is narrower, the actions show their icon alone first, then the kinds (their shape stays, and each name appears when you point at its button); on a phone the zoom buttons go too, since you zoom by pinching.
![]()
The Inspector
On the Graph tab the right panel is the Inspector of the map. It opens on the component itself; click an entity to inspect it instead. It shows:
- The summary of the whole map, at the top: If you change Button: 12 entities across 3 levels, and under it the split by kind, such as 5 tokens · 1 style · 6 components · 2 patterns. A kind with none is left out. It does not change when you pick an entity, and it counts the whole map, not only what the filters leave on screen. When nothing uses the component, it says Nothing uses it.
- The entity: its kind, its name and where it lives (a folder or a collection), then Lives in, with the marks for Figma and code. A pattern has no Lives in: it is neither in Figma nor in code.
- Value: a colour token shows its colour, and a component set shows how many of its variants the change reaches.
- Relation to the centre: for the centre itself, This is the centre: the entity you would change. For an entity the change reaches directly, Affected directly and the relation of its line. For one farther away, Affected at level N through … and the path from the centre to it, as chips.
- Connections: Used by N, how many entities use this one. Like the summary, it counts what the filters hide.
The panel ends with up to four buttons, each there only when it has somewhere to go:
- Open panel opens the entity’s own panel over the page. A colour, effect or grid style has none, so only a text style gets the button.
- Open pattern appears on a pattern and goes to its page, under Patterns. It is a link to a page, not a panel over this one.
- Open in Docs opens a component’s page, or the page of a token synced from Figma (see A token’s page below). A style, a pattern, and a token that lives only in code, have no Docs page to open from here.
- Centre graph here maps what uses this entity instead. It is off on the centre, which is already centred, and on a pattern, which cannot be made the centre.

Centring on another entity
Double-click an entity, press Centre graph here, or press C on a focused one, and the map is drawn again with that entity at its centre (a pattern is the exception: it cannot be a centre, so these do nothing on it): if I changed this one instead, what would I affect? The breadcrumb at the top left of the map, headed Centre, lists the centres you went through, oldest first (Button › Icon); click an earlier one to go back to it. The last one is where you are. The filters stay as they were, and what you had opened closes.
Nothing you do on the map is saved. Leaving the tab forgets the filters, what you opened and the centres you went through, and the tab opens again on the component itself. The page’s address carries the tab (?tab=graph), not a centre you moved to.
When there is no map
- While it is read, the tab shows a spinner.
- If nothing uses the component, it says Nothing uses it.
- If the page has no component to map, it says There is nothing to map for this component yet.
- If the read fails, it says Could not load the blast radius. with a Try again button, and the Inspector says Could not load the graph. Try again reads the same centre again, and the breadcrumb stays.
- If the entity you are centring on is no longer there, the read says That entity is not available. and offers the same Try again; the breadcrumb takes you back to a centre that is.
A token collection’s or a style’s page
Clicking a token collection or a style in the panel opens its page. At the top are its name, its sync status and when it was last synced. A token collection also shows how many variables and modes it has; a style shows what kind it is — a text, color, effect or grid style — and its description from Figma when it has one.
A token collection also lists its tokens, grouped by role, under its head: colours as swatches, font families, sizes and weights as samples of text, radii as boxes, spacing as bars, and whatever Grails cannot place in an Unknown Role at the end, with one column per mode. You do not write that part, and it is never out of date. How a token gets its role has the detail.
Each token’s name in that list is a link to the token’s own page, with its documentation and what a change to it would affect: see A token’s page below.
The Color group can be seen as a list or as a grid. A List / Grid switch sits beside the group’s name. List is the table every group has, with one column per mode. Grid draws a card for each token:
- The swatch, over a checkerboard when the colour has some transparency.
- The token’s name, a link to its page. Under a heading the card shows only the last part of the name (
300undertw-raw/blue); the whole name is the link’s tooltip. - Its value. Click it to copy exactly what it shows, in the notation and for the mode on screen; a toast confirms it. A mode in which the token has no value shows a dash, and a reference Grails cannot follow says so.
- The token it points to, when the token is an alias: an arrow and that token’s name (
→ tw-raw/blue/300), a link to its page when it has one. A token deleted in Figma has no page, so its name is plain text.
The cards are grouped under headings by path: the name up to its last /, so tw-raw/blue/300 sits under tw-raw/blue. Tokens whose name has no / come first, under no heading. A token hidden from publishing says so on its card.
Above the cards, the grid has its own choices:
- Format: Original, Hex, RGB, HSL or OKLCH. It opens on Hex. Original is the value as the token stores it; for a token that lives in code, it is the notation your repository wrote (see A collection that lives in code below). A value that cannot be written in the notation you picked is shown as stored, with a line that says so (Could not be written as RGB, shown as stored).
- Mode, only when the collection has more than one. The grid shows one mode at a time, starting with the collection’s default; the list keeps a column for every mode.
Which view opens. A collection with one mode opens as a grid, and one with several opens as the list. What you pick (the view, the mode and the format) is kept in the page’s address, for example ?view=grid&mode=Dark&format=oklch. Copy the address and whoever opens it sees the same view, and a reload keeps it. A choice that matches what the page opens on is not written, so a link without it opens the default view.
Only Color has a grid. Every other group (Spacing, Corner radius, Unknown Role and the rest) is always the table, and a collection with no colours has no switch. Export → Markdown is not affected: it writes the table with every mode, whichever view you are on.
The rest of the page is its documentation, and it works like a component’s Docs tab: it opens to read, and the bar at the bottom holds Edit, Import, Export and More, with Copy link to this view. While you edit, Add block lists every shape except Props, which only a component can have; Save and Done work the same. On this page, on the right, lists the Title blocks.
With nothing written, the page says so and offers admins and editors Add block and Import Markdown, except on a phone.
It is the same documentation the Tokens and Styles sections open in their panel. That panel is for reading, whatever your role, and its bar at the bottom has Open in Docs: you write the documentation here, in Docs, and what you write shows there (the panel has the detail). A mention of a text style opens its panel in Typography; a mention of a token collection is shown as its name and does not open anything yet.
A collection that lives in code
A token collection can also come from your repository (uploaded with grails-cli sync). It has the same page, and what you see depends on where it lives:
- In Figma and in code. The page is the Figma collection’s, with a Design / Code switch at the right end of its header, as a component with both sides has. Design is everything described above. Code shows the tokens your repository holds for the same collection, under a line that says where they come from (From acme-ui · 40 tokens · 2 modes). Design is the default. The side you pick goes in the page’s address (
?src=code), so whoever opens the link sees the same side and a reload keeps it; switching reads nothing again. Export → Markdown writes the side you are on. - Only in code. The page shows the code tokens alone, with no switch. Its header says where it lives (the code mark), the repository, and how many tokens and modes it holds. Its documentation can be read but not edited for now, whatever your role: the bar at the bottom has Export and More, and no Edit.
- Only in Figma. The page is the one described above, with no switch.
The Code side is the Figma view over your repository’s tokens:
- The same groups by role, a table for each, with the values resolved. A token your repository defines as a reference to another shows that token’s name, like an alias in Figma.
- One column per mode, in the order your repository gives them. The code has no default mode, so none comes first; a mode the code leaves unnamed is called Default.
- The Color group can be a grid too, with the same List / Grid switch, Mode and Format. Original shows each colour as your repository wrote it (
oklch(0.6 0.2 250),rgb(51 102 255),color(display-p3 0.2 0.4 1)), and Hex, RGB, HSL and OKLCH are converted from that colour. For a token that points at another, Original is the notation of the token it ends at. A colour outside sRGB is painted with the nearest colour sRGB can show, and the text still says what you wrote. - A code token’s name is plain text. A code token has no page of its own yet, so nothing links to one.
- Text styles are not listed here. They are in Typography. A collection that holds nothing else says so: This collection holds only text styles (3). They are listed in Typography. A collection with no tokens at all says This collection has no tokens in the code.
- If the tokens cannot be read, the page says so (Tokens could not be loaded.) instead of showing an empty collection.
A token’s page
A token synced from Figma has a page of its own. It has no row in the panel on the left, which lists collections and not their tokens: open the page of the token’s collection and click the token’s name in its list. While you are on a token’s page the panel marks the token’s collection, and a link above the token’s name, with the collection’s name, goes back to it.
At the top are the token’s name and, beside it:
- Where it lives: the Figma mark is always lit, and the code mark lights when the token also exists in your code.
- Its sync status.
- What it is for: its role, the group the collection’s page lists it under (Color, Spacing, Font size…). A token Grails could not place in a role has none here, and its value carries its Figma type instead.
- Its value in each mode, drawn as the collection’s list draws it: a swatch, a sample of text, a box. A collection with several modes names each value by its mode.

The page has two tabs and opens on Docs:
- Docs is the token’s documentation: the blocks the Tokens section shows in its panel. It works like a component’s Docs tab: it opens to read, and the bar at the bottom holds Edit, Import, Export and More, with Copy link to this view. There is no History, because a token has no versions to list. While you edit, Add block lists every shape except Props, which only a component can have; Save and Done work the same, and going to the Graph tab with unsaved changes asks first, as the Anatomy tab does on a component. On this page, on the right, lists the Title blocks. With nothing written, the tab says so and offers admins and editors Add block and Import Markdown, except on a phone.
- Graph is the token’s blast radius, the same map as a component’s, with the token at its centre: what uses the token, in columns by level (Direct, Level 1 and so on), with the bar at the bottom to filter it and the Inspector on the right. The Graph tab above explains each part. The map is read when you open the tab and not before.
The page’s address carries the tab (?tab=graph); Docs, the tab it opens on, writes nothing.

Pages
Folders
Pages are grouped by folder — a label like Brand or Foundations that several pages share. Folders appear in alphabetical order, and pages with no folder are collected first under Ungrouped.
A folder is a label, not a container, and that decides what its menu does (hover over the folder’s name to see it):
- Rename folder moves every page in it to the new name. Renaming onto a folder that already exists merges the two, and Grails tells you before you confirm.
- Delete folder removes the label: its pages stay exactly as they are and become ungrouped. No page is deleted.
- A page’s folder never affects its link. A page’s address comes from its title when you create it and then stays put, whichever folder it is in.
Each page
Each page shows its icon and its title, and the page you are reading is highlighted. The icon is the one you chose in the page’s header; a page without one shows the document icon. Hover over a page to open its menu:
- Move to folder… — pick an existing folder, or name a new one.
- Delete page… — see Deleting a page below.
Creating a page
Press Create Doc page, fixed at the bottom of the panel while the Pages tab is open (or at the bottom of the Overview), and give the page a title. The title becomes the page’s address, so Voice and Tone becomes a page at /docs/page/voice-and-tone, and Grails opens it for you straight away, with Add block and Import Markdown in the middle of the empty page.
Two things happen automatically and are worth knowing about:
- Two pages can share a title. The second one gets a slightly different address; neither creation fails and you are not asked to pick another name.
- Renaming later keeps the original address. This is deliberate: a link you shared in Slack three months ago keeps opening the right page after someone tidies up its title.

Writing a page
Opening a page shows it to read: its identity at the top, its content below, and its bar at the bottom — the same bar as a component’s Docs tab:
- Edit opens the page for writing: its header and its blocks. Only admins and editors have it, on a screen at least 768 pixels wide.
- Import adds blocks from a .md file or pasted Markdown, as on a component’s Docs tab. Only admins and editors have it, on a screen at least 768 pixels wide.
- Export saves the page as a Markdown file, or copies it as Markdown.
- More (⋯) holds Copy link to this view, and for admins and editors Move to folder… and Delete page….
While you edit, the bar holds Add block, Save and Done, which work as they do on a component’s Docs tab. On this page, the panel on the right, lists the page’s Title blocks.
The page header
While you edit:
- Icon — click it to pick an emoji. It is what makes a page findable in a long list at a glance.
- Title — click and type. It saves by itself, shortly after you stop typing.
- Summary — one line describing the page, under its title.
The header saves on its own as you edit it. The content below does not — see the next section.
The content
Below the header is the same block editor used for component documentation, so everything you already know about writing documentation in Grails applies here: section titles, prose, tables, specs, guidelines, use cases, checklists, props, images, files, and mentions of other entities.
Three shapes are worth knowing apart before you start a long page, because they look interchangeable and are not:
- Title breaks the page into sections. It is a heading with a level you choose, and it carries no body — the prose that follows goes in a Text block below it.
- Table lays values out in rows and columns: breakpoints and their sizes, a support matrix. You edit it in place, dragging column widths that then stay where you put them.
- Specs defines. Each row names something and says what it is — the shape you want for a glossary, a set of parts, or the states of a component.
Full guidance on choosing between them, and on what each editor offers, is in Documentation blocks.
Mentioning things, and being mentioned
Inside a page you can mention any component, token or style, and the mention resolves to that entity’s current name — so a rename in Figma updates your page by itself, rather than leaving the old name written down.
Clicking a mention opens that entity’s panel on top of the page, so you can check something without losing your place. A text style opens in Typography; a color, effect or grid style shows its name and opens nothing, and says so when you point at it. If the entity was deleted, or is not in this project, the mention says so: it reads Missing component (or token, style…), or its panel says it was not found.
Available actions
| Action | Roles | What happens |
|---|---|---|
| Read pages | Admin, Editor, Viewer | Anyone on the team can read every page in the project |
| Inspect a component and compare its variants | Admin, Editor, Viewer | Nothing on a component’s page changes the component: it shows its latest sync |
| Open a token, or copy an element’s spec | Admin, Editor, Viewer | The spec is copied to your clipboard |
| Export a component’s anatomy as PNG or Markdown | Admin, Editor, Viewer | The file is saved to your computer |
| Switch the preview between Screenshot and Schematic, and pick the mode each token collection is read in | Admin, Editor, Viewer | Screenshot / Schematic and Modes change only what you see |
| Compare a component’s Design and Code in Both | Admin, Editor, Viewer | The two schematics, the wired tables and the summary; Matches filters the pairs |
| Link and unlink the parts of a component’s Design and Code, and their values | Admin, Editor | Drag between rows, Link on a row, or Unlink on a wire in Both; each change offers Undo |
| Read a component’s documentation | Admin, Editor, Viewer | On its Docs tab |
| Export documentation or a page as Markdown | Admin, Editor, Viewer | The file is saved to your computer, or the text copied |
| Import Markdown into documentation or a page | Admin, Editor | The blocks join the page being edited; Save keeps them |
| Write a component’s documentation | Admin, Editor | Edit on its Docs tab; saved together when you press Save |
| See what a change to a component would affect | Admin, Editor, Viewer | Its Graph tab reads the map; nothing is changed |
| Open a token’s page | Admin, Editor, Viewer | Click the token’s name in its collection’s page, or Open in Docs in the Graph Inspector or in the token’s documentation panel |
| Switch a collection between its Design and Code sides | Admin, Editor, Viewer | The Design / Code switch in its header changes only what you see; the side goes in the page’s address and nothing is saved |
| Read a collection that lives only in code | Admin, Editor, Viewer | Its tokens, grouped by role; its documentation can be read, not edited for now |
| See a collection’s colours as a grid, and pick a mode and a format | Admin, Editor, Viewer | The List / Grid switch, Mode and Format change only how the group is drawn; the choice goes in the page’s address and nothing is saved |
| Copy a colour’s value from the grid | Admin, Editor, Viewer | Click the value on its card; it is copied in the notation on screen |
| Read a token’s documentation, and see what a change to it would affect | Admin, Editor, Viewer | Its Docs and Graph tabs; nothing is changed |
| Write a token’s documentation | Admin, Editor | Edit on its Docs tab; saved together when you press Save |
| Filter, open and centre the map | Admin, Editor, Viewer | Changes only what you see; leaving the tab starts the map again |
| Open an entity’s panel or its page from the Inspector | Admin, Editor, Viewer | Open panel opens it over the page; Open in Docs goes to the page of a component or of a Figma token |
| Read documentation in a panel | Admin, Editor, Viewer | The panel is for reading; Open in Docs, in its bar, goes to the entity’s page |
| Start writing from an empty panel | Admin, Editor | Edit in Docs opens the entity’s page already editing, on a screen at least 768 pixels wide |
| Create a page | Admin, Editor | The page is created and opened |
| Rename a page | Admin, Editor | The title changes; the page’s link stays the same |
| Edit the summary or icon | Admin, Editor | Saved automatically, shortly after you stop typing |
| Write and save blocks | Admin, Editor | Edit in the page’s bar; saved together when you press Save |
| Move a page to another folder | Admin, Editor | The page appears under its new folder; its link stays the same |
| Delete a page | Admin, Editor | The page and its blocks are removed permanently |
| Rename a folder | Admin, Editor | Every page in it moves to the new name |
| Delete a folder | Admin, Editor | Its pages become ungrouped; no page is deleted |
Deleting a page
Permission notes
Nothing on a component’s page edits the component itself: its Anatomy and Graph tabs read the same for every role, and its Docs tab is written by admins and editors. The one thing the Anatomy tab lets admins and editors change is the links between a component’s Design and Code in Both; viewers see the links without the controls. A token’s page works the same way: its Graph tab reads the same for every role, and its Docs tab is written by admins and editors.
A token collection that lives only in code is read the same way by every role, and no role can edit its documentation for now: nothing writes documentation to a collection that has no Figma counterpart yet. Once a collection exists in Figma too, its page is the Figma collection’s and works as described above.
The documentation panel that opens over a page is for reading, whatever your role: it has no Add block and no Save, and a checklist step is ticked in Docs, not in the panel.
A viewer can read every page in the project and a component’s documentation, and cannot change anything: no Create Doc page button, no page or folder menus in the panel, and no Edit in the bar, so no editable title, summary or icon and no way to add or edit blocks.
Editors and admins have identical permissions over pages. There is no per-page permission — a page is readable and writable by exactly the people who can read and write the project it belongs to.