Skip to content

Theme and fonts

Widgets have no values of their own. They only reference the named steps of the theme, so changing a value changes every widget.

A Theme is Colors plus Metrics, and fields of both can be accessed directly:

t := kiln.catppuccin(.Mocha)
t.radii[.MD] = 2
t.sizes[.Control] = 40
t.locale = kiln.locale_de()
kiln.set_theme(t)

Or pass it to run:

kiln.run(app, {title = "Meine App", theme = t})
procwhat
catppuccin(flavor)complete theme: .Mocha, .Macchiato, .Frappe (dark), .Latte (light)
catppuccin_colors(flavor)only the colors
default_metrics()4px based spacing, 36px controls, 16px body text, Iosevka
theme()a copy of the active theme
set_theme, set_colors, set_metricsreplace all, only colors, only metrics

The default is Catppuccin Mocha.

stepvalues
Space.None, .XS, .SM, .MD, .LG, .XL (0, 4, 8, 12, 16, 24)
Radius.None, .SM, .MD, .LG, .Full
Size.Track, .Bar, .Dot, .Mark, .Control, .Avatar, .Drawer, .Dialog, .Menu, .Toast
TextStyle.Caption, .Body, .Subtitle, .Title, .Headline
Tone.Default, .Muted, .Faint, .Primary, .Info, .Success, .Warning, .Danger
Surface.None, .Window, .Sunken, .Raised

Font sizes are font_base * font_ratio^(style - Body), so font_base = 16, font_ratio = 1.25 gives 12.8, 16, 20, 25 and 31.25.

Everything in the theme is in units. The UI scale (monitor DPI times zoom) turns units into pixels. Scale in the Config sets the zoom, can scale with the window height (fit_height) or ignore the DPI. Ctrl +/−/0 changes the zoom unless no_zoom_keys is set.

kiln compiles subsets of Iosevka (resources/kiln-regular.ttf, resources/kiln-bold.ttf, about 80 KB each) into the binary, so apps start from any directory. -define:KILN_EMBED_FONTS=false loads font_files at runtime instead. font_data in the theme takes any font file in memory.

Any character a font has can be shown: glyphs are baked on demand the first time a character is measured (one frame later it is there). Characters the font lacks come from font_fallbacks, a list of fonts in memory that are tried in order, e.g. a full font, a CJK font or a symbol font:

theme := kiln.catppuccin(.Mocha)
cjk, _ := os.read_entire_file("fonts/NotoSansSC-Regular.otf", context.allocator)
fallbacks := [?][]u8{#load("fonts/Iosevka-Regular.ttf"), cjk}
theme.font_fallbacks = fallbacks[:] // must stay alive while the app runs

To make a subset of another font:

Terminal window
odin run tools/subset_font -- resources/Iosevka-Regular.ttf resources/kiln-regular.ttf
odin run tools/subset_font -- resources/Iosevka-SemiBold.ttf resources/kiln-bold.ttf

or with fonttools:

Terminal window
pyftsubset Iosevka-Regular.ttf --unicodes=U+20-7E,U+A0-17F,U+2010-205E,U+20AC,U+2190-21FF,U+2212,U+22EF,U+2302,U+25A0-25FF,U+2600-2609,U+2630,U+2699,U+2713-2718 --output-file=kiln-regular.ttf