Usage rules

The decisions that are not visible in the catalogue but hold the product together. When two designs disagree, this section decides.

The layout of a screen

Frame

Top bar → breadcrumbs → page header → content. Breadcrumbs are left out only on the root pages of a section, where they would point at themselves.

Content

Exactly one main pattern: a table, a step-by-step setup, grouped cards, a detail with tabs, or metrics. Two are never mixed — neither would have enough room.

Actions

The primary action sits at the right of the header, never floating. Row actions are icon-only and always at the end of the row, so a list has one place to look for them.

Yes and no

Five situations that keep coming back in admin screens and keep inviting the same wrong answer. The right-hand column is the one that holds.

Yes and no
SituationNoYes
A longer edit of a recordA side drawer squeezed next to the listA modal — room to explain and focus on the thing at hand
Confirming a deleteA solid red surfaceAn outline button and the entity name in the text
The result of savingA “Done” modalA toast with an undo action
An error in a formOnly a toast at the topA message at the field that has the error
An empty listAn empty table with a header rowAn empty state with the first action

Text

  • A button names the outcome: Add country, not OK. A reader decides by what will happen, not by the fact that something is being confirmed. Cancelling is always Cancel.
  • A field label is a noun without a colon; the hint below the field is a full sentence with a full stop. The two roles of the text are then distinguishable without reading them.
  • An error says what to do: “The company number must have 8 digits”, not “Invalid value”. A message that does not reveal the next step stops the user just as surely as no message.
  • A technical term is used only where production itself uses it. The vocabulary switch in the account menu (Plain / Expert) toggles between the everyday and the technical variant — so every term needs both.
  • No exclamation marks, no emoji and no “Oops”. An error is a fact, not an apology.

Pinning the kit

The kit is installed from git, so the pin is the whole agreement. It points at a release tag, never at a commit.

"@forgmatic/ingot": "github:zm-sw/ingot-ui-kit#v1.1.0"
  • A commit looks more precise and is in fact less safe. The version number moves only at a release, so every commit between two releases carries the previous one's number — a single version string names many different trees.
  • A package manager caches a git dependency under its name and version. Under one number it may therefore hold a different tree than the pin points at — and nothing warns you: package.json, package-lock.json and node_modules all agree.
  • Releases are tagged, so a tag is exactly one version and exactly one tree. It is the only pin that holds.
  • When a type check cannot find a symbol you can see in the kit's own source, suspect the install before the kit: compare the installed file against the tag, not against a version number, and clear the cache before measuring again. Matching numbers prove nothing.

What the package offers

The package has more than one entry. This is not tidiness: with only the main one, a marketing page would pull in the form runtime to get a pricing table, and every consumer would rewrite the theme plumbing — the first to spell a storage key differently loses the reader's choice on half their pages.

EntryWhat comes out of it
@forgmatic/ingotThe primitives. Button, table, form, dialog — everything with a page under Components.
@forgmatic/ingot/marketingThe public-page blocks. Hero, steps, pricing, FAQ. A marketing site gets them without the form runtime.
@forgmatic/ingot/themeTheme and accent: read the choice, store it, resolve it against the system, put it on the document. No React.
@forgmatic/ingot/theme-init.jsThe anti-flash script. Belongs in <head> as a plain, non-deferred <script> — a module is deferred, which is the flash.
@forgmatic/ingot/tailwind-presetThe Tailwind preset. The utilities are named after the tokens, so without it half the classes mean nothing.
@forgmatic/ingot/tokens.cssThe token values. One import, light and dark and all five accent families.
@forgmatic/ingot/tokens.jsonThe same tokens as data, for tools outside the web.

The theme entry deliberately knows neither React nor where the choice really lives. In the product the account owns it, so it follows the operator across devices; browser storage is only the fast mirror the anti-flash script and the first render read.