hellabs design system
Solarized, one monospaced face, terminal corners. The prose version is
Design/Brand.md
in the kb repo.
Palette
Ground and ink
Every colour utility resolves through a runtime variable, so one class serves both
themes — bg-surface
is correct in dark and in light, and a dark:
twin is almost always a mistake. Ratios are measured against that theme's page ground,
dark first. On surface
every ratio drops by roughly a quarter, which is why muted
text belongs on the ground and fg
on a card.
bg
the page ground
#00212b · #fdf6e3
surface
cards, inputs, the header
#073642 · #eee8d5
raised
hover and active states
#0a4150 · #e4dcc4
line
borders and dividers
#1a5263 · #cec5a9
emph headings, values, anything you read first #eee8d5 · #002b36 — 13.68 / 13.92:1
fg body text #93a1a1 · #586e75 — 6.27 / 4.99:1
muted labels and secondary text — on the page ground only #839496 · #5f747c — 5.30 / 4.55:1
Accents
Eight, and what each one means
Type
One face, five steps
Display — 30px/600
Heading — 24px on a phone, 18px from sm: up
Body — 14px/400. Long-form panel copy sits here: settings help, empty states, the explanation of what a token is about to do before you press the button.
Label — 12px, tracked, upperNumeric — 1234567890 · 00:41:07 · 99.7% · tabular
Motif
Bands rising to the right at 16.3°
Controls
Buttons, inputs, and 44px of touch
Data
Tables and description lists
| event | at | state |
|---|---|---|
| channel.follow | 20:14:03 | delivered |
| channel.subscribe | 20:14:31 | delivered |
| channel.raid | 20:16:52 | dropped |
- bundle
- panel — app.js, app.css
- second bundle
- overlay — overlay.js, overlay.css, transparent ground
- icons
- heroicons, via the icon component
Components
Catalyst ports — foundation/0006
Badge, heading, text, divider, description list, dialog, switch and field join button and table from the design-system merge. Preflight and the panel shell compose from these rather than raw markup.
Badges
Description list
- Channel
- No channel yet
- Overlay bundle
- transparent ground, no LiveSocket
Switch
Stream mode
A plain checkbox styled as a knob — no JS dependency.
Dialog
Rules
The ones that are not preferences
- Tokens, never raw hex. A colour that is not in the palette is a bug.
- One monospaced face at every size. No proportional headline, ever.
- The overlay bundle's ground is transparent — never dark, never a bg-* class on the root.
- The overlay bundle must never import LiveView; a reconnect would re-mount an on-air alert.
- No graphic and no page ever carries an overlay URL, an ingest URL or a token — not even as decoration.
- Motion yields to prefers-reduced-motion; a viewer cannot opt out of someone else's stream.