UI Style Guide — Tokens & Scale
UI Style Guide · Foundations
Typography
| Font file | Where used | Sizes |
|---|---|---|
Orbit-Regular-Headers.ttf |
Main menu big title only | 48 px |
PIXEARG_.TTF |
Main menu buttons & labels only | 14–16 px |
Onest-Bold.ttf |
Every in-game panel, tooltip, dialog, pause menu body | 9–16 px |
Rule: Pixel font (
PIXEARG_) is main menu only. Once the game world is visible — building panels, unit details, pause menu, hab display, dialogs — use Onest-Bold.Size scale
Onest-Bold / in-game
Hab Module Alpha
Colonist Assignment
Assign worker · Power: 4.2 kW
O2: Oxygen Gen A · 3 / 4 slots filled
Power: 12.5 kW · Sleeping · 30s
PIXEARG_ / main menu only
NEW GAME
LOAD GAME
Colour
Two layers: primitive tokens hold raw hex values with material/visual names — no intent implied. Semantic tokens map a role onto a primitive. Components only ever reference the semantic layer; they never touch a primitive or hardcode a hex value. Change a primitive hex and the whole system ripples.
Primitive palette
Material and visual names only — a primitive name says what it looks like, never where it is used.
Darks
--void-black#0A0A10
--basalt#151618
--obsidian#1E1F21
--lunar-dust#1F232A
--regolith-slate#2A2F37
--crater-beige#3A3A2E
Neutrals
--dust-shadow#8A8A7A
--cream#EAE0CD
--ghost-white#F5F5F0
Accents
--arc-cyan#4AC1F2
--arc-lime#7EEB92
--arc-yellow#F8E870
--arc-orange#F28C38
--arc-red#F23649
--fern-green#4CAF50
--plasma-purple#A855F7
Semantic tokens
Map a design role onto a primitive. Components reference --interactive, never --arc-cyan. To retheme, change the primitive; all semantics follow.
| Semantic token | → Primitive | Role | |
|---|---|---|---|
| Surfaces | |||
--surface-base | --void-black | Deepest background, modal overlay | |
--surface-raised | --basalt | All panel / HUD backgrounds | |
--surface-inset | --obsidian | Inset cards, list rows, code blocks | |
--surface-border | --regolith-slate | Dividers, card borders, separators | |
| Text | |||
--text-body | --cream | All primary readable text | |
--text-dim | --dust-shadow | Labels, secondary info, section headings | |
--text-on-light | --void-black | Text on cream-filled buttons (btn-primary) | |
| Interactive | |||
--interactive | --arc-cyan | Selection, active tabs, progress bars, highlights | |
--interactive-subtle | --arc-cyan @10% | Active tab background tint | |
| Status | |||
--status-ok | --arc-lime | Health bar, working colonist, success state | |
--status-caution | --arc-yellow | Energy bar, low-priority alert | |
--status-warn | --arc-orange | Hunger bar, moderate alert, warning text | |
--status-danger | --arc-red | Critical health, damage, destructive action text | |
--status-special | --plasma-purple | Mission-complete state only | |
| Action fills (button backgrounds) | |||
--fill-primary | --cream | btn-primary — single CTA per panel | |
--fill-secondary | --regolith-slate | btn-secondary — nav and supporting actions | |
--fill-danger | --arc-red @15% | btn-danger — destructive actions | |
Never use a primitive token in a component. If you reach for
--arc-cyan directly, ask: "is there a semantic token for this role?" Components reference --interactive; only the token mapping file ever touches --arc-cyan. This means a full retheme requires changing only the primitive values.neon-edge (#00D4FF) removed. It is perceptually indistinguishable from ARC Cyan and had no assigned semantic role. Use
--arc-cyan for all selection/highlight needs. plasma-purple is reserved for mission-complete state only — do not use as a general accent.Cyan usage in panels — when to restrain
ARC Cyan is a high-energy accent, not a neutral UI colour. Use it sparingly inside information panels to avoid visual fatigue. It should mark critical state changes, not routine information.
| Context | Cyan usage | Example |
|---|---|---|
| Selection / active state | ✓ Use cyan boldly | Selected colonist in list (cyan bg + bright text). Mission tab active (cyan highlight). Selected building (cyan border outline in game world). |
| Progress / measurement | ✓ Use cyan as fill | Progress bars, resource meters, thermal load bar. Cyan = "it's running" or "capacity used". |
| Normal status text | ✗ Use Dust Shadow instead | Power: 12.5 kW, Operator: Boris, Worker slot: 2/4. These are informational, not warnings. Use #8A8A7A. |
| Inactive UI controls | ✗ Use neutral slate | Slider track background, toggle switch background when off, disabled button text. Keep these visually quiet. |
| Panel text labels | ✗ Never use | Never colour routine labels or section headers in cyan. Use Dust Shadow (9–10 px, uppercase). |
Soviet-functional aesthetic: Cyan should feel like an exception, not the default. Your eye should move to cyan elements because something changed state or needs attention — not because every UI element is bright. Panels are places to read, not to be bombarded with colour. Default to Cream (text), Dust Shadow (secondary), and Slate (backgrounds). Cyan earns its place only when it signals state.
Spacing & Corner Radius
Spacing tokens
Panel padding — modal
20 px
Panel padding — compact
12 px
Section separation — large
12 px
Section separation — compact
6–8 px
Inline element gap (icon+label)
4 px
Bottom bar button gap
8 px
Corner radius
Modal / menu panel
12 px
12 px
Inline / tech card
4 px
4 px
Progress bar
2 px
2 px
Do not mix radii within the same panel hierarchy. If the outer container is 12 px (
card_bgr_panel.tres), every inset card inside it is 4 px (--r-card). Never 6 px or 12 px on inset elements. card_front.tres must be updated from 6 px → 4 px.