@arag
A house CSS design system for MONT, TAAY, ARDX materials, the kiosk app and the
mobile app. Plain CSS, native cascade layers, oklch() colour, bilingual Latin and
Mongolian Cyrillic. A <link> tag is the whole install.
Complete and verified: tokens, reset, base element defaults, fifteen components and the utility layer. Nothing in the sidebar is a placeholder any more.
Principles
Zero dependencies, zero build
No Sass, no PostCSS, no config file, no class scanner, no JIT engine, no JavaScript. Nothing to install and nothing to run. The package is four CSS files, and consuming it is one link.
<link rel="stylesheet" href="node_modules/@arag/css/src/index.css">Native CSS only
Everything the system relies on ships in Chrome, Edge, Firefox and Safari:
@layer, custom properties, nesting, color-mix(),
oklch() and light-dark(). What the
preprocessors were for, the platform now does. See
browser support for the version floor.
Tokens all the way down
Every colour, space, radius, shadow, font size, duration and easing curve is a custom property. Component CSS contains no raw values at all — that rule is greppable, and it holds today.
# must return nothing
grep -rnE ':\s*[0-9.]+(px|rem|em|ms)\b' src/base.cssNo priority-raising declarations, ever
Overriding is done with cascade layers, not force. Your application CSS is unlayered, which places it above all six of the system's layers, so plain authoring wins by default. There is not one such declaration in the package, and that is also greppable.
# must return nothing
grep -rn '!important' src/Bilingual by default
Mongolian Cyrillic runs roughly 15–25% longer than the equivalent Latin string. Components size to their content: no fixed button widths, no single-line assumptions in nav, cards or tables. Font stack and line height are tokens. Read the full constraint →
Create a new order
Шинэ захиалга үүсгэх
Create a new order
Шинэ захиалга үүсгэх
Those two panels are one page in one theme. Dark mode is
light-dark() switched by color-scheme, which means
[data-theme] works on any subtree — not just the root.
How theming works →
What is in the box
| File | Layer | Lines | Does |
|---|---|---|---|
src/reset.css | reset | 245 | Unstyles browser defaults. Deliberately token-free, so it is correct standalone. |
src/tokens.css | tokens | 553 | Every literal value in the system. 293 custom properties. |
src/base.css | base | 528 | Element defaults — body, headings, links, tables, form controls, focus. |
src/index.css | — | 27 | Declares the layer order, then imports the three above. This is the entry point. |
src/components/ | components | 5547 | Fifteen components, one file each: accordion, alert, badge, button, card, carousel, collapse, dialog, field, menu, progress, scrollspy, table, tabs, toast. |
src/utilities.css | utilities | 355 | Static, hand-picked classes. No generator, no arbitrary values. Next session. |
The token surface
275 custom properties, of which 71 are internal ramp generators you will rarely touch directly and 204 are the public surface.
| Group | Count | Shape |
|---|---|---|
| Colour | 180 | 5 ramps × 11 steps, 54 semantic roles, 6 state controls, 71 generators |
| Typography | 24 | 3 stacks, 7 fluid sizes, 4 leadings, 4 weights, 3 trackings |
| Space & size | 19 | 10 space steps, 9 size ceilings and minimum targets |
| Radius, border, shadow | 24 | 8 radii, 7 border and focus-ring, 9 shadow |
| Z-index & motion | 22 | 10 stacking levels, 5 durations, 6 easings, 1 shorthand |
Each token page renders its tokens as live swatches in both themes, with the
browser-resolved value beside each name — read at runtime, so the docs cannot drift from
tokens.css.
What this is not
Not a Tailwind or Bootstrap clone. There is no utility generator, no arbitrary-value syntax, no scanner, no config file and no JavaScript framework layer. Utilities will be a static, hand-picked file of roughly 120–150 classes. If it cannot be named, it is not needed.