@cmgfi/omni-ds
v0.1.3
Published
Omni design system: tokens, type, component recipes and the adoption brief, as plain CSS with no framework.
Readme
Omni
Omni is a design system. It is one agreed set of colours, type sizes, spacing steps and component recipes, so that every tool built on it looks and behaves like one product rather than six.
This package is all of it. Nothing outside it is needed.
Install
npm install @cmgfi/omni-dsEverything below is a plain file in node_modules/@cmgfi/omni-ds/. There is no
JavaScript to import and no build step: link the stylesheets, or point your
bundler at them. The Omnify assistant skill, which adopts Omni into an existing
application, is installed separately and looks for this package in
node_modules before it does anything else.
The two stylesheets
Add both, in this order. The paths below are relative to this folder; from a page
of your own they are node_modules/@cmgfi/omni-ds/omni.css and
node_modules/@cmgfi/omni-ds/omni-components.css, or whatever your bundler
resolves them to.
<link rel="stylesheet" href="omni.css">
<link rel="stylesheet" href="omni-components.css">omni.css is the foundation: the four typefaces, the values, and the ready-made
text classes that read them. omni-components.css is the component recipes, the
real CSS behind each control, and it is the one that makes a class such as
.omni-btn do anything at all. Every rule in it reads a value the foundation
declares, so the foundation is linked first. Every length in the system is
measured against the page's base text size, which browsers set to 16 pixels
unless something has changed it.
Then put the class omni on one element. Everything Omni does happens at or
below that element, and nothing above it changes at all. Which element it is
depends on one question: does Omni own this page, or is it a guest on somebody
else's?
If Omni owns the page
Put the class on <html>, and nowhere else.
<html class="omni">
<head>
<link rel="stylesheet" href="omni.css">
<link rel="stylesheet" href="omni-components.css">Both of them, in that order, and those two lines are the whole of the wiring.
The foundation declares the values; every component recipe reads them. A class
such as .omni-btn is declared in the second stylesheet and nowhere else, so
a page that links only the first one applies the class and renders an element
that looks as though nobody had styled it.
<html> rather than <body> or a wrapper, for a reason that costs an afternoon
to find: dialogs, menus and toasts are attached by the browser to the
end of <body>, so a class placed there misses them, and a value defined inside
a scope cannot be read from outside it.
The page is yours, so the base text size is too. If anything has changed it, set
it back to 16 pixels on the same <html> element that carries the class.
If Omni is a guest inside an application somebody else owns
A guest is Omni placed inside a page it does not own: a panel, a drawer, a card or a dialog that somebody else's application renders you into. Put the class on the outermost element of that area, and no higher.
<div class="omni">
<!-- the panel, drawer or card you were given, and everything inside it -->
</div>Never on <html>, and never on <body>. You do not own either one here.
Omni's values written there would reach the whole application rather than your
part of it, which is a change you were not given permission to make, and they
would land where the application's own names can collide with them.
If your area opens a dialog, a menu or any other layer that the browser attaches to the end of the page, that layer lands outside your element and loses every Omni value. Put the same class on the layer's own outermost element too.
You cannot set the base text size as a guest: the root element is not yours,
and every length in Omni is measured against it. If the application's base size
is not 16 pixels, say so before scaling anything locally. adoption-kit/ is
where a guest's path through the system is written.
Either way it is the same class and the same two stylesheets. Only the element it sits on changes.
Keep that element's text size at 16 pixels. Omni's lengths are multiples of
the page's root text size, so a page that sets anything else renders every
spacing step, control height and corner at that page's ratio rather than at the
size the system is drawn at. If the root is yours, set it. If it is not, because
another design system has already built its own scale on it, the adoption brief
in adoption-kit/ opens by saying what the two honest choices are and what each
one costs. A pixel edition of the value file, which removes the question
entirely, is in this folder, and it has an entry point of its own: link
omni-guest.css instead of omni.css, keep omni-components.css after it,
and every length arrives already in pixels whatever the page sets its root to.
If you find yourself typing a literal colour, size or corner radius, stop. There is a named value for it, and if there genuinely is not, that is worth telling us about rather than filling in locally.
Where to start
| Open | For |
|---|---|
| design.html | The system explained: how type, colour, form and light and dark modes work, and the rules that cannot be broken. Start here. |
| tokens.html | Every value, shown rather than described, beside the component it belongs to. |
| DESIGN.md | The same content as design.html, as plain text. |
| TOKENS.md | The same content as tokens.html, as plain text, for searching and for spotting what changed between versions. |
| adoption-kit/ | What to run against your own code before you start. find-literals.js reports every hard-coded colour, size and radius it finds, which is the list of things to replace. |
What is in here
| | |
|---|---|
| omni.css | The foundation, in one link. Imports the typefaces, the values, the text classes and the register classes, in the order they have to arrive in. |
| omni-guest.css | The same foundation, for a block inside somebody else's page. Every length arrives in pixels, because a guest cannot set the host's root font size and every relative length would otherwise drift with it. Link this instead of omni.css, not as well. |
| omni-components.css | The component recipes, in one link. Link it after omni.css: it is what makes a class such as .omni-btn do anything, and every rule in it reads a value omni.css declares. |
| tokens.css | Every named value the system defines: colour, type, spacing, corners, borders, shadow, motion. A named value means a colour or a spacing step can be changed in one place and take effect everywhere. |
| type-classes.css | The ready-made text classes. Each one sets a size, a weight, a line height and a typeface together, so the four cannot be mismatched. |
| registers.css | Three classes for the three voices the interface speaks in: the product, the assistant, and machine-written detail such as timestamps and counts. |
| fonts/ | The four typefaces, hosted here rather than fetched from anywhere: Onest for headings and display, Epilogue for reading text and what a person types, Petrona for what the assistant itself says, and DM Mono for labels, the words on controls, navigation and figures. Which face a given piece of text gets is decided by the face slots, not by picking one: see DESIGN.md § 3. |
| components/ | The recipes themselves, one file per family: the real CSS for controls, fields, badges, rows, tables, panels, the top bar, and the rule that stops a theme change animating. omni-components.css loads them for you, so nothing here has to be linked by hand; read them to see how a value is meant to be used. One file, host.css, is the page chrome for the two pages above and is deliberately not loaded by either stylesheet. |
| tokens.guest-px.css | The same values as tokens.css, with every length written in pixels, for when Omni sits inside an application somebody else owns. You do not link this file yourself: omni-guest.css does. It redeclares every value under the same selectors, so the pixel lengths win. It cannot be swapped in for tokens.css, because omni.css imports that file itself. The lengths in tokens.css are multiples of the page's base text size, and only the owner of a page can set that; this file does not depend on it. |
Licence and support
The four typefaces are published under the SIL Open Font Licence. Everything else here is CMG Financial internal material, for use inside CMG products.
