Everything about how the overlay looks is one theme name plus an optional [style] table. This
page is the whole catalogue: with it alone you can assemble a complete custom appearance without
reading any source.

The three-step chain

Every visual value is resolved once, at start-up, along one chain:

[style] override  →  named theme (colours only)  →  built-in default

So an override wins over the theme, the theme wins over the default, and a value you do not mention
falls through to whatever the next step supplies. [style] may be given with no theme at all, in
which case the overrides land on top of the default theme.

Two consequences worth stating outright:

  • A theme is a palette and nothing else. It can change colours; it cannot change a font or a
    dimension. Switching theme therefore recolours the overlay and never moves it — dark and
    light produce a surface of exactly the same size and position.
  • A dimension outside its range is clamped, not rejected. The clamp is reported, the nearer
    bound is used, and everything else in your file still applies.
theme = "light"

[style]
highlight        = "#c04a2f"
font_family      = "JetBrains Mono"
text_size        = 0.85
width_fraction   = 0.95

Colours

Eleven keys. Each accepts #rgb, #rrggbb or #rrggbbaa, and the two columns are what each
built-in theme sets it to.

Form: #rgb, #rrggbb, or #rrggbbaa. Alpha defaults to opaque when omitted. No other
notation is accepted (research R25).

Set by a theme: yes — these eleven values are what a built-in theme sets (FR-045, FR-049).

Key Draws Default (dark) light
backdrop Overlay background #17171ced #f7f7faed
highlight Highlighted entry background #336bb8 #2e70cc
active_mark Active-workspace mark #6bb873 #298c47
text Primary entry text (workspace name) #ebebf0 #1c1c24
text_highlighted Primary text on the highlighted entry #ffffff #ffffff
text_dim Secondary text (window names) #a8a8b3 #595966
text_dim_highlighted Secondary text on the highlighted entry #dbe6f5 #e0ebfa
miniature Miniature background #292930 #e6e6ed
window Tiled window rectangle fill #4d5261 #c2c7d6
window_floating Floating window rectangle fill #61667a #adb5c9
window_edge Window rectangle edge #858c9e #737a8f

Two of the eleven are marks rather than fills, and what they draw is worth stating:

  • highlight fills the background of the entry the keyboard is currently on — the one that
    commits when you release the modifier.
  • active_mark marks the workspace each monitor is already displaying. In the grid
    presentation it is the frame around the miniature; in the list it is the short bar down the left
    edge of the row, whose thickness is mark_width. It is drawn as a mark rather than as a
    different fill precisely so it survives being highlighted at the same time: one entry can carry
    the highlight background and the active_mark frame together, and the two answer different
    questions — where you are about to go, and where you are now.

With several monitors you will see several active marks at once, one per monitor, since each
monitor has its own current workspace. Every other workspace in the overlay carries none.

The built-in themes

There are two, and their values are the two columns of the table above: theme = "dark" (the
default) and theme = "light". Naming one sets all eleven colours at once; any of them can still
be overridden individually on top of it. An unknown name is reported, the default applies, and
every other setting in your file still applies.

text_highlighted is white in both, because the highlight stays a saturated blue in both.

Contrast is not validated. A low-contrast or fully transparent combination renders exactly as
asked — if the overlay comes up unreadable, that is the palette you wrote.

Fonts

Set by a theme: no. Fonts are shared defaults, not per-theme values (FR-049, research R24). They are
reachable only as overrides.

Key Form Default Range Notes
font_family string Sans Any family name. An absent family is substituted by the platform; text stays readable and nothing is reported (US4-AS5).
text_size float 0.78 0.3..=1.0 Fraction of the row’s text height. The row height follows it, so text is never clipped by its own row.

Dimensions

Ten values, each a number with a documented range. These are the ones that are clamped rather than
rejected, so an out-of-range value is safe to experiment with — you will be told what was used.

Set by a theme: no — same reason as fonts. Values are logical units, scaled per monitor by the
existing rule (FR-055), so no per-monitor variants exist.

An out-of-range value is clamped to the nearer bound and reported; it is not rejected and does
not fall back to the default (FR-054, research R26).

Key Form Default Range Governs
text_line_height integer 20 8..=200 Entry text height; drives row height
row_padding integer 8 0..=100 Vertical padding within a row
overlay_padding integer 12 0..=200 Overlay’s outer padding
width_fraction float 0.8 0.1..=1.0 Overlay width cap, as a fraction of the monitor
height_fraction float 0.8 0.1..=1.0 Overlay height cap, as a fraction of the monitor
grid_cell_width integer 240 40..=2000 Miniature cell width
grid_cell_height integer 135 40..=2000 Miniature cell height
grid_gap integer 12 0..=200 Gap between grid cells
corner_radius float 0.28 0.0..=1.0 Corner rounding, as a fraction of row height
mark_width float 0.12 0.0..=1.0 Active-mark width, as a fraction of row height

Why these ranges

The bounds are not cosmetic; they are what makes SC-023 provable — that no valid combination can
produce an unusable overlay:

  • width_fraction and height_fraction cap at 1.0, so the overlay can never exceed its monitor.
  • text_line_height and the grid cell sizes have non-zero minimums, so the viewport arithmetic in
    ui/layout.rs cannot divide by zero and a row can always hold its text.
  • Nothing here can make entry size depend on the number of workspaces — entries stay fixed-size and
    the overlay scrolls, exactly as FR-019 requires (FR-053).
  • The cap wins over the entry size. These ranges are absolute while the cap is a fraction of
    the monitor, so a large enough entry on a small enough monitor asks for more than the cap allows
    — a grid_cell_width of 2000 on an 800-pixel panel, say. ui/layout.rs holds the overlay to
    the cap and lets that one entry be clipped by the surface edge, rather than scaling it down to
    fit, which FR-019 forbids. Below that extreme the row and column counts are chosen so the result
    fits, and the clamp never engages.
  • Zero means zero. row_padding, overlay_padding and grid_gap admit 0, and a zero there
    is carried through to the buffer rather than floored to one device pixel — a floor would be the
    one measurement that did not scale per monitor, which FR-055 forbids.

What is deliberately not a setting

Listed so their absence reads as a decision rather than an oversight (Principle II):

Not a setting Why
Icon size Follows the resolved text height (FR-052), so it cannot disagree with the row it sits in.
Icon tint or recolouring Program artwork is drawn as supplied (FR-051). Only the placeholder follows text.
Per-monitor or per-presentation values One appearance applies everywhere (FR-048).
Background blur, shadows, gradients, animation Out of scope — this feature makes existing drawing configurable, it adds no new visual elements (spec Assumptions).
Resolution timing Not user-facing; settled in research R27 and the spec’s Assumptions.
A second colour notation One form, by decision (research R25).