Visual theme tokens used by the renderer.
v0.2 shipped the minimum surface the renderer actually reads
(:header, :focus, :selection, :border). v0.4 adds the
general-purpose tokens app authors reach for —
:primary, :accent, :muted, :error — and ships three built-in
themes plus caps-aware color downgrade so the same theme renders
reasonably on truecolor, 256-color, 16-color, and monochrome
terminals.
Tokens (each a Harlock.Render.Style.t()):
:header— table column headers. Default:bold: true.:focus— active focus indicator. Default:reverse: true.:selection— selected rows / cells. Default:bg: :cyan.:border— default box border style. Default:%Style{}(no fg/bg).:primary— primary brand / accent surface. Default:fg: :cyan.:accent— secondary accent. Default:fg: :magenta.:muted— de-emphasised text. Default:dim: true.:error— error / destructive surface. Default:fg: :red.
Setting a theme
Harlock.run(MyApp, init_arg, theme: %Harlock.Theme{
focus: %Style{reverse: true, fg: :yellow},
selection: %Style{bg: :blue, fg: :white}
})
# Or use a built-in:
Harlock.run(MyApp, init_arg, theme: Harlock.Theme.builtin(:dark))Omitting the option uses Harlock.Theme.default/0, which matches the
pre-theming hard-coded values byte-for-byte. The default theme is
intentionally minimal — apps that want a visible identity pick a
built-in or build their own.
Built-in themes
:default— what v0.3 produced. Minimal, terminal-native colors.:dark— opinionated dark palette suitable for cave-dwellers.:high_contrast— bright primaries / strong borders, biased for readability over aesthetics.
Look up with Harlock.Theme.builtin/1.
Reading inside a callback
def view(model) do
accent = Harlock.Theme.get(:primary)
text("hello", style: accent)
endThe runtime stashes the theme in the process dictionary before
invoking update/2 and view/1, mirroring the Harlock.Focus pattern.
Don't call get/1 outside a Harlock callback — there's nothing in the
dictionary.
Summary
Functions
Build a theme from a keyword list or a map. Unspecified tokens take their default values.
Return one of the built-in themes by name. Available: :default,
:dark, :high_contrast.
The default theme. Matches the pre-theming hard-coded values exactly so
apps without a custom theme render byte-identically across v0.3 and
v0.4. New v0.4 tokens (:primary/:accent/:muted/:error) carry
sensible defaults but are not read by the renderer itself — they're
available only to apps that explicitly opt in via get/1.
Look up a theme token. Returns the value from the theme installed by the runtime, or the default if no theme is in scope.
Types
@type t() :: %Harlock.Theme{ accent: Harlock.Render.Style.t(), border: Harlock.Render.Style.t(), error: Harlock.Render.Style.t(), focus: Harlock.Render.Style.t(), header: Harlock.Render.Style.t(), muted: Harlock.Render.Style.t(), primary: Harlock.Render.Style.t(), selection: Harlock.Render.Style.t() }
@type token() ::
:header | :focus | :selection | :border | :primary | :accent | :muted | :error
A theme is the bag of styled tokens the renderer looks up.
Functions
Build a theme from a keyword list or a map. Unspecified tokens take their default values.
@spec builtin(:default | :dark | :high_contrast) :: t()
Return one of the built-in themes by name. Available: :default,
:dark, :high_contrast.
@spec default() :: t()
The default theme. Matches the pre-theming hard-coded values exactly so
apps without a custom theme render byte-identically across v0.3 and
v0.4. New v0.4 tokens (:primary/:accent/:muted/:error) carry
sensible defaults but are not read by the renderer itself — they're
available only to apps that explicitly opt in via get/1.
@spec get(token()) :: Harlock.Render.Style.t()
Look up a theme token. Returns the value from the theme installed by the runtime, or the default if no theme is in scope.