About¶
Why it exists¶
Abilian builds and maintains a range of business applications. They share a server stack and share nothing visually: each one accumulated its own Bootstrap fork, its own spacing habits, its own idea of what a "card" is. The cost is not aesthetic. It is that a fix in one is a fix in one, and a developer moving between them starts over.
The usual answer is to adopt an off-the-shelf kit. The usual result is that the kit's opinions leak into the product and its 300 independent values cannot be retuned as a set — so "make it denser for this client" becomes a fork.
The position¶
Tabler provides the taste; we provide the implementation.
Tabler is a mature, well-proportioned admin design language, and reproducing its judgement is cheaper than inventing one. But consuming it means inheriting Bootstrap, a build step, and a vocabulary nobody here controls.
So this is not a Tabler wrapper. It is an independent implementation, held to Tabler's measurements by a calibration harness that renders 78 elements side by side against the real thing and compares them property by property. It reports zero differences.
That separation is the whole point. Tabler decides how it looks; we decide how it is built. When the two goals diverge — and they do, on accessibility — we can take the divergence deliberately instead of forking.
Where the reference is not enough
Tabler's success green measures 2.48:1 as text on its own tint. The floor for body text is 4.5:1. Rather than silently ship the failure or silently diverge, that became a knob: --ads-contrast: 0 is the reference's own palette, 1 moves every intent to a readable ink without touching a single fill, border or tint. Both ends are asserted by tests.
Status¶
Usable and in use by one reference application. Not yet proven across a second, which is the current priority.
| Stylesheet | 16 files, 3,034 lines |
| Vocabulary | 27 knobs, 128 derived tokens, 256 classes |
| Reference application | 50 routes, 4 shell layouts, 6 live islands, 6 languages, RTL |
| Visual parity | 0 properties differ across 78 elements vs Tabler |
| Linter | 18 rules, 0 findings |
| Automated checks | 88 passing — 32 library, 25 application, 31 in a real browser |
Roadmap¶
- A second application. The reference demo proves the system can build the reference demo. Nothing yet proves it survives a different domain and a developer who did not write it. In progress.
- A real screen-reader pass. Everything tested so far is what a browser can be asked about the DOM, which catches absent semantics but not wrong ones.
- Density tuning. The knobs sit at Tabler's values so parity can be measured. Abilian's applications are dense tools and may well want a smaller base type and a sub-1 space scale — a product decision to take once there is a second application to take it against.
- Package and publish, so "vendored and hashed" becomes a real guarantee rather than a local convention.
Design principles¶
- The menu is closed. A value you cannot name does not exist. Needing one is a signal to add a token, never to reach for a literal.
- Derive, do not enumerate. If two values must move together, one is computed from the other.
- Enforcement is the linter, not the document. A document is a probability; most-of-the-time is not a design system.
- The look cannot exist without the meaning. State a person can perceive is an attribute —
aria-current,aria-pressed,aria-invalid— and the stylesheet keys off that attribute, so there is nothing for an author to remember.
Licence and credits¶
Built by Abilian. Visual language after Tabler by Paweł Kuna. Icons are Tabler Icons. Interactive islands use situ.