Ingot is the Forgmatic design system — a set of decisions about colour, typography, space and behaviour. It is not a component gallery.
Ingot is the Forgmatic design system — a set of decisions about colour, typography, space and behaviour, from which the tenant admin, the platform admin and the public pages are all assembled. It is not a component gallery. It is the agreement on what work on the shop floor looks like once it is translated onto a screen.
Tokens and classes in one place. A screen is assembled from them — not from styles written on the spot. That is why changing a decision shows up everywhere, and not only where someone happens to remember it.
For designers and developers alike. The same vocabulary on both sides means the design and the code talk about the same thing — nobody translates between two descriptions of one screen.
A new component is not born inside a screen. It appears in the system first, gets a rule and a name, and only then is used.
Data before decoration
An admin interface is a dense record of reality. No ornamental surfaces and no gradients — a surface exists so that numbers can be read on it.
Contrast makes the structure
The page background is always darker than a card. Hierarchy is carried by spacing and a rule, not by a shadow and not by colour.
One accent
The accent is one family of four tokens. An extra colour means a new meaning — and that meaning has to be named, not invented inside a screen.
Facts are monospaced
Numbers, codes, identifiers, dimensions and times belong in the monospaced face with tabular figures. Prose explains, monospace measures.
Tenant = platform
Both admin surfaces share one top bar and one set of components. They differ by the badge next to the brand and by the content of their sections — never by a look of their own.
The user’s language
Labels speak the language of the shop floor, not of the database. A technical term appears only where production itself uses it.
The system has four layers and each answers a different question. Before adding anything, decide which one it belongs to — the layer decides where the thing is changed and what a change touches.
| Layer | Where it lives | When to reach for it |
|---|---|---|
| Tokens | The root of the system — the one place a value is declared. | Colour, spacing, radius, shadow, typeface. |
| Elements | The layer above the tokens — button, field, badge. | Individual controls and markers. |
| Blocks | Compositions of elements — a table, a step card, an empty state. | Parts of a screen that repeat. |
| Shell | The application frame — top bar, breadcrumbs, main area. | The frame of every admin page. |
Everything is imported from one place:
import { IngotTable, IngotEmptyState } from "@/ingot";Always through this one entry point, never by a deeper path to a specific file. What comes out of it is the kit’s public interface and changes are announced; what does not is internal and may be renamed or split at any time. That interface includes the types an element asks for — IngotColumn for table columns, say.
A new primitive appears once a concrete screen asks for it. Once there is such a caller, three things belong together in one change: the component and its export from @/ingot, a page on this site with a live demo, and the first screen that genuinely uses it.
The page must render the demo with the real component. Copied JSX looks identical on the day it is written and lies quietly from the second day on.
Every component page has the same shape: a live demo with the code that produces it, when to use it and when not to, a table of properties, accessibility and translations. Where the first version deliberately cannot do something, that is listed too. The rule about translations is common to every element, so it has a page of its own — Translations.
Rule of thumb. If you are writing your own colour, spacing or radius into a screen, one of two things is true: either there is a token you did not find, or the system is missing a decision. Both are settled in the system, not in the component.