Veila
Themes

Normandy

Minimal centered layout with a clock and pill input

Normandy theme preview

Background Image

The background image comes from Wallhaven. If you'd like to use this specific image as your lock screen background, download it here

Use This Theme

You do not need to copy the full config below just to activate Normandy. The preset is already bundled into Veila.

Use either of these:

theme = "normandy"

Or from the CLI:

veila theme set normandy

If the daemon is already running, veila theme set also tries to reload the config immediately.

Minimal Overrides

The Normandy theme already works without extra config. Use a small ~/.config/veila/config.toml like this only when you want to change personal details such as avatar, wallpaper, weather, now playing, or clock or date format.

theme = "normandy" # Use the bundled Normandy theme

[visuals.outputs]
ui_mode = "single" # Show the full UI on one monitor. Use "all" for every monitor

[background]
mode = "file" # Background source (accepts "file", "gradient", "layered", "radial", or "solid")
path = "/path/to/wallpaper.jpg" # Wallpaper image path used when mode = "file"

[weather]
enabled = true # Enable background weather fetching (accepts true or false)
location = "Normandy" # Place name used for weather lookup (accepts any geocodable city or place name)
unit = "celsius" # Temperature unit (accepts "celsius" or "fahrenheit")

[visuals.now_playing]
enabled = true # Show the now-playing widget when MPRIS media metadata is available (accepts true or false)

[visuals.clock]
format = "24h" # Clock format (accepts "24h" or "12h")

You can keep this file minimal. Any key you do not set continues to come from the bundled Normandy theme

By default, ui_mode is single, so the full lock UI appears on the primary or selected monitor while other monitors stay protected by secure background curtains.

If you want the full UI on every monitor, set [visuals.outputs].ui_mode to all. See Monitor Output for the full configuration reference.

Fonts

Veila can use both bundled fonts and fonts installed on your system.

The Normandy theme uses only bundled fonts, so it works out of the box without installing extra font files:

  • Geom
  • Google Sans Flex
  • Nunito

You can still override any font_family with a system font. For example:

[visuals.clock]
font_family = "Japanola"
font_weight = 700
font_style = "normal"

For a font you downloaded manually, install it into your local font directory and rebuild the font cache:

mkdir -p ~/.local/share/fonts
cp ~/Downloads/Japanola.ttf ~/.local/share/fonts/
fc-cache -fv

Then verify the exact family name your system sees:

fc-match Japanola
fc-list | rg -i japanola

Use the exact family name from fc-match or fc-list in font_family.

Font weight and style matter. If the installed font only provides a regular 400 face but the config asks for 700, or if the font is italic but the config asks for normal, Veila may pick a fallback font instead of the one you expected. When a font appears to not work, first check the real family name, available weight, and whether the face is normal or italic.

Preset Reference

The config below shows the bundled Normandy preset as a reference. It is useful when you want to understand how the theme is built, copy it into ~/.config/veila/themes/, or override only selected parts in your own config.toml.

You do not need to paste this whole block unless you want to customize it.

[background]
mode = "file"
path = "/path/to/wallpaper.jpg"
color = "#324948"
blur_strength = 12
dim_strength = 34

[battery]
enabled = true

[weather]
enabled = false

[visuals.clock]
format = "24h"
style = "standard"
meridiem_font_size = 22
meridiem_x = 6
meridiem_y = 7
font_family = "Google Sans Flex"
font_weight = 400
color = "rgba(255, 255, 255, 0.4)"
font_size = 88
halign = "center"
valign = "center"
x = 0
y = -60

[visuals.date]
format = "long"
font_family = "Google Sans Flex"
font_weight = 400
color = "rgba(255, 255, 255, 0.4)"
font_size = 22
halign = "center"
valign = "center"
x = 0
y = 0

[visuals.input]
placeholder = "Password"
background_color = "rgba(255, 255, 255, 0.08)"
border_color = "rgba(255, 255, 255, 0.08)"
border_width = 3
width = 310
height = 54
radius = 50
mask_color = "#ffffff"
font_family = "Google Sans Flex"
font_weight = 400
font_size = 16
halign = "center"
valign = "center"
x = 0
y = 100

[visuals.status]
mode = "inline"
rejected_color = "#FFD5D5"
pending_color = "#ECECEC"

[visuals.eye]
color = "rgba(255, 255, 255, 0.72)"

[visuals.caps_lock]
color = "rgba(255, 255, 255, 0.52)"

[visuals.placeholder]
color = "rgba(255, 255, 255, 0.6)"

[visuals.avatar]
enabled = false

[visuals.username]
enabled = false

[visuals.keyboard]
background_size = 46
radius = 23
background_color = "rgba(255, 255, 255, 0.05)"
color = "rgba(255, 255, 255, 0.68)"
size = 16
halign = "right"
valign = "top"
x = -24
y = 21

[visuals.battery]
background_color = "rgba(255, 255, 255, 0.05)"
background_size = 46
radius = 23
color = "rgba(255, 255, 255, 0.68)"
size = 20
halign = "right"
valign = "top"
x = -78
y = 21

[visuals.weather.icon]
size = 40
opacity = 80
halign = "left"
valign = "bottom"
x = 40
y = -112

[visuals.weather.temperature]
font_size = 40
font_family = "Geom"
font_weight = 600
letter_spacing = 0
color = "rgba(255, 255, 255, 0.73)"
halign = "left"
valign = "bottom"
x = 40
y = -70

[visuals.weather.location]
font_size = 22
font_family = "Google Sans Flex"
font_weight = 400
color = "rgba(214, 227, 255, 0.58)"
halign = "left"
valign = "bottom"
x = 40
y = -44

[visuals.now_playing]
enabled = false
fade_duration_ms = 320

[visuals.now_playing.artwork]
size = 44
radius = 8
opacity = 90
halign = "left"
valign = "center"
x = 10
y = 0
relative_to = "now_playing"

[visuals.now_playing.artist]
width = 318
color = "rgba(255, 255, 255, 0.39)"
font_family = "Google Sans Flex"
font_size = 16
font_weight = 400
halign = "left"
valign = "top"
x = 65
y = 10
relative_to = "now_playing"

[visuals.now_playing.title]
width = 318
color = "rgba(255, 255, 255, 0.69)"
font_family = "Google Sans Flex"
font_size = 16
font_weight = 400
halign = "left"
valign = "bottom"
x = 65
y = -10
relative_to = "now_playing"

# Now playing backdrop
[[visuals.backdrop]]
enabled = true
name = "now_playing"
show_when = "now_playing"
mode = "blur"
color = "rgba(255, 255, 255, 0.05)"
blur_strength = 12
radius = 10
border_color = "#FFFFFF18"
width = 400
height = 60
halign = "right"
valign = "bottom"
x = -40
y = -40

Normandy uses bundled Veila fonts, so the default clock and text styling work without installing extra font files.

On this page