Design token system for Mob apps.
A theme is a compiled %Mob.Theme{} struct — a flat map of semantic tokens
for colors, spacing, radii, and scale factors. The renderer resolves these
tokens at render time so every component picks up the active theme
automatically.
Using a named theme
Named themes are plain modules that export theme/0. Pass the module to
use Mob.App:
use Mob.App, theme: Mob.Theme.ObsidianOverride individual tokens without leaving the theme:
use Mob.App, theme: {Mob.Theme.Obsidian, primary: :rose_500}Anyone can publish a theme as a Hex package — any module with theme/0
returning a Mob.Theme.t() works:
use Mob.App, theme: AcmeCorp.BrandThemeBuilding a theme from scratch
Pass a keyword list of overrides against the neutral base:
use Mob.App, theme: [primary: :emerald_500, type_scale: 1.1]Or change the theme at runtime (e.g. for accessibility or user preference):
Mob.Theme.set(Mob.Theme.Obsidian)
Mob.Theme.set({Mob.Theme.Obsidian, type_scale: 1.2})
Mob.Theme.set(primary: :pink_500)Base theme
When no theme is set the renderer uses the neutral base — plain dark grays with a standard blue primary. Functional, not opinionated. Good enough for hello world; swap in a named theme when you want personality.
Token reference
Semantic color tokens
:primary — main action colour (default :blue_500)
:on_primary — text/icons on primary (default :white)
:secondary — secondary action colour (default :gray_600)
:on_secondary — text/icons on secondary (default :white)
:background — page/screen background (default :gray_900)
:on_background — text on background (default :gray_100)
:surface — card / sheet background (default :gray_800)
:surface_raised — elevated card background (default :gray_700)
:on_surface — text/icons on surface (default :gray_100)
:muted — secondary/placeholder text (default :gray_500)
:error — error state colour (default :red_500)
:on_error — text/icons on error (default :white)
:border — dividers and outlines (default :gray_700)Spacing tokens (scaled by space_scale)
:space_xs → 4 × scale
:space_sm → 8 × scale
:space_md → 16 × scale
:space_lg → 24 × scale
:space_xl → 32 × scaleRadius tokens
:radius_sm → theme.radius_sm (default 6)
:radius_md → theme.radius_md (default 10)
:radius_lg → theme.radius_lg (default 16)
:radius_pill → theme.radius_pill (default 100)Scale factors
type_scale: 1.0 # multiply all text sizes by this
space_scale: 1.0 # multiply all spacing tokens by this
Summary
Functions
Build a theme from a keyword list of overrides against the neutral base.
Return the currently active theme (or the neutral base if none is set).
Return the neutral base theme.
Set the active theme. Accepts
Types
@type color_value() :: atom() | non_neg_integer()
@type t() :: %Mob.Theme{ background: term(), border: term(), error: term(), muted: term(), on_background: term(), on_error: term(), on_primary: term(), on_secondary: term(), on_surface: term(), primary: term(), radius_lg: term(), radius_md: term(), radius_pill: term(), radius_sm: term(), secondary: term(), space_scale: term(), surface: term(), surface_raised: term(), type_scale: term() }
Functions
Build a theme from a keyword list of overrides against the neutral base.
Mob.Theme.build(primary: :emerald_500, type_scale: 1.1)
@spec current() :: t()
Return the currently active theme (or the neutral base if none is set).
@spec default() :: t()
Return the neutral base theme.
Set the active theme. Accepts:
- A compiled
%Mob.Theme{}struct - A theme module (
Mob.Theme.Obsidian) - A
{module, overrides}tuple - A keyword list of overrides against the neutral base