Custom Layer
The custom layer sits between base and utility. It holds reusable component patterns -- things that are more than a single property (so they don't belong in utilities) but not opinionated enough for the base layer (which only styles bare HTML elements).
Axiom ships a handful of patterns here. You're expected to add your own. Because the utility layer loads last, utilities can always override custom-layer styles when you need a one-off adjustment.
Table Patterns
The base layer gives tables transparent backgrounds, collapsed borders, and comfortable padding. That's all. Stripes and hover effects are opt-in here, because they're stylistic choices rather than document defaults.
Striped Rows
Add .table-striped to any <table>. Even-numbered body rows get a barely-perceptible tint -- 3% black in light mode, 3% white in dark mode. This works on any background because it's a transparent overlay, not an absolute colour.
| Name | Department | Location |
|---|---|---|
| Alice Johnson | Engineering | London |
| Bob Smith | Design | Berlin |
| Carol White | Marketing | New York |
| David Brown | Engineering | London |
Row Hover
Add .table-hover for an interactive highlight on mouseover. The two classes compose naturally.
| Name | Department | Location |
|---|---|---|
| Alice Johnson | Engineering | London |
| Bob Smith | Design | Berlin |
| Carol White | Marketing | New York |
| David Brown | Engineering | London |
Datatable Example
A realistic table composed entirely from base-layer defaults, custom-layer patterns, and utility classes. No custom CSS required. This is the kind of table you'd see in a dashboard or admin panel.
| Name | Role | Status | Last Active |
|---|---|---|---|
| Alice Johnson alice@example.com | Admin | Active | 2 hours ago |
| Bob Smith bob@example.com | Editor | Active | 5 hours ago |
| Carol White carol@example.com | Editor | Away | 2 days ago |
| David Brown david@example.com | Viewer | Active | Just now |
| Eva Martinez eva@example.com | Admin | Inactive | 3 weeks ago |
| Frank Lee frank@example.com | Editor | Active | 12 hours ago |
This example uses .table-striped and .table-hover from the custom layer. Everything else -- the wrapper's .overflow-x-auto, the badge colours, the text alignment and sizing -- is composed from utility classes. The table itself needs two inline style overrides (margin-bottom: 0 and border: none) to sit cleanly inside the wrapper's border.
Buttons
The base layer styles <button> and <input type="submit"> directly. The custom layer adds class-based access so you can apply the same treatments to any element.
Primary and Secondary
.button-primary and .button-secondary map to the same token pairs the base layer uses for submit and reset buttons. Use them on <button type="button">, anchors, or anything else that needs to look like a button.
Button Reset
.button-reset strips a <button> back to bare semantics. No background, no border, no padding. You keep keyboard handling, focus styles, and disabled states. Useful for icon buttons, custom triggers, or anywhere the base button styling gets in the way.
Toggle Switch
A styled checkbox that looks like a toggle. Native form behaviour, keyboard accessible, works with screen readers. Compose with .toggle, .toggle-track, and .toggle-label.
Wrapper
.wrapper centres content with a max-width (default 1600px). Override with --wrapper-max-width.
<div class="wrapper">
<!-- content centred at 1600px max -->
</div>
<div class="wrapper" style="--wrapper-max-width: 800px">
<!-- narrower wrapper -->
</div>