UI Style Guide · Foundations

Primitive & semantic tokens, typography scale, colour system, and spacing rules. These foundations underpin every component and panel.

Typography

Font fileWhere usedSizes
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
16 px · Section header
Hab Module Alpha
14 px · Sub-header
Colonist Assignment
12 px · Body / button
Assign worker · Power: 4.2 kW
10 px · Secondary
O2: Oxygen Gen A · 3 / 4 slots filled
9 px · Fine print
Power: 12.5 kW · Sleeping · 30s
PIXEARG_ / main menu only
16 px · Button
NEW GAME
14 px · Label
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.

--void-black#0A0A10
--basalt#151618
--obsidian#1E1F21
--lunar-dust#1F232A
--regolith-slate#2A2F37
--crater-beige#3A3A2E
--dust-shadow#8A8A7A
--cream#EAE0CD
--ghost-white#F5F5F0
--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→ PrimitiveRole
Surfaces
--surface-base--void-blackDeepest background, modal overlay
--surface-raised--basaltAll panel / HUD backgrounds
--surface-inset--obsidianInset cards, list rows, code blocks
--surface-border--regolith-slateDividers, card borders, separators
Text
--text-body--creamAll primary readable text
--text-dim--dust-shadowLabels, secondary info, section headings
--text-on-light--void-blackText on cream-filled buttons (btn-primary)
Interactive
--interactive--arc-cyanSelection, active tabs, progress bars, highlights
--interactive-subtle--arc-cyan @10%Active tab background tint
Status
--status-ok--arc-limeHealth bar, working colonist, success state
--status-caution--arc-yellowEnergy bar, low-priority alert
--status-warn--arc-orangeHunger bar, moderate alert, warning text
--status-danger--arc-redCritical health, damage, destructive action text
--status-special--plasma-purpleMission-complete state only
Action fills (button backgrounds)
--fill-primary--creambtn-primary — single CTA per panel
--fill-secondary--regolith-slatebtn-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.

ContextCyan usageExample
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
Inline / tech card
4 px
Progress bar
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.