A visual system for an instrument, not an admin panel.
Ionia exists to make a compliance judgment defensible. Everything here follows from that: time is the primary quantity, provenance travels with every number, and no state that carries contractual meaning relies on hue alone. Radix Colors and Radix Icons supply the raw material; the taxonomy on this page is what turns them into a product.
Colour
Radix cyan as accent, Radix slate as neutral. Both themes are authored from the start; dark swaps values, never classes. The Metronic orange is retired — an orange accent competes with the amber that carries at-risk meaning, and in a product where colour is compliance evidence that collision is not affordable.
Typography
Archivo for interface, JetBrains Mono for identifiers, timestamps and durations. Seven steps, no more. Wired through font CSS variables, not a literal family string.
Space, radius, elevation, motion
3px on severity tags and micro-badges, 6px on controls, 10–12px on surfaces, pill on status chips. The shape difference between a 3px severity tag and a pill status chip is deliberate — see Taxonomy.
Surfaces are separated by a 1px border and a background step. Shadow is reserved for things that float: popovers at level 1, modals and drawers at level 2. No ad-hoc shadow on cards.
- 100ms
- Hover, focus, colour change
- 160ms
- Overlay in, drawer, row state change
- 240ms
- Threshold crossing, toast arrival
- ease
- cubic-bezier(.2,.7,.3,1)
No entrance animation on static content. No per-row or per-cell delay chains. Data-available to fully-settled stays under 300ms. prefers-reduced-motion removes animation rather than shortening it.
Compact also drops the secondary feature line under each subject, taking a 25-row page from six screens to three.
15×15 geometric grid at 16px nominal. Retires the four Keenicons webfont files, the hand-written inline SVGs, and Lucide. One system, one weight, one metric.
Status and severity taxonomy
One canonical mapping, used by the list, the detail header, the timeline, notifications and the report. Status is stage; severity is impact. They are different axes, so they get different shapes.
A High-severity ticket that is Closed is a normal, common object. Side by side, the sharp monospace tag reads as impact and the soft pill reads as stage — before any colour is processed. Hue alone would collapse them into one undifferentiated smear of chips.
The time language
Ionia's whole reason to exist. Four provenance sigils, four clock bands, one gauge, and a rule that red is earned rather than default.
The current response cell renders red whether four minutes or four days remain. That teaches operators to ignore red, which is the worst outcome a compliance interface can produce. In this system red appears only past the obligation, and its magnitude is stated in the same breath.
Components
Each with its full state matrix. Every Metronic class the current build leans on has a replacement here before the vendored bundle is deleted.
Migration sequence
Nothing is deleted before its replacement is in place. Each phase ships on its own and leaves the product working.
-
{{ ph.n }}{{ ph.title }} {{ ph.tag }}
{{ ph.body }}
The access token in localStorage and the client-side role guard are real weaknesses, but they are an authorisation change with its own impact analysis. This work leaves both untouched and raises them for review rather than altering them under cover of a visual revamp.