| 1 |
@{! variants = default, night } |
| 2 |
# Alloy yazi theme — @{meta.name} |
| 3 |
# |
| 4 |
# Palette source: makeover's themes/@{meta.id}.toml. |
| 5 |
# Filetype icons: none. See the [icon] section at the foot of this file. |
| 6 |
# |
| 7 |
# Written against yazi 26's theme schema, which is not the one this file was |
| 8 |
# first authored for. Yazi reorganised it and does not complain about the |
| 9 |
# difference: an unknown section or key is dropped in silence, so the old |
| 10 |
# spellings parsed cleanly and simply never painted anything. What moved: |
| 11 |
# |
| 12 |
# [manager] -> [mgr] |
| 13 |
# hovered / preview_hovered -> [indicator] current / parent / preview |
| 14 |
# tab_active / tab_inactive -> [tabs] active / inactive |
| 15 |
# tab_width -> gone |
| 16 |
# [status] mode_* -> [mode] normal_main / normal_alt / select_* / unset_* |
| 17 |
# [status] separator_* -> [status] sep_left / sep_right, as open/close pairs |
| 18 |
# [status] permissions_* -> [status] perm_type / perm_read / perm_write / perm_exec |
| 19 |
# [select] -> [pick] |
| 20 |
# [completion] -> [cmp] |
| 21 |
# [help] exec -> [help] run |
| 22 |
# |
| 23 |
# Yazi loads its own theme-dark.toml or theme-light.toml first, chosen by the |
| 24 |
# terminal's background, and treats this file as an override on top. That |
| 25 |
# choice tracks this file's polarity by itself: rio's background is |
| 26 |
# surface.page from the same render, so the preset underneath is the light one |
| 27 |
# under the day render and the dark one under the night render, without |
| 28 |
# anything here saying so. Only keys named here are ours; anything omitted |
| 29 |
# stays yazi's, which is why the preset underneath matters at all. |
| 30 |
|
| 31 |
# : Manager {{{ |
| 32 |
[mgr] |
| 33 |
cwd = { fg = "@{content.primary}" } # content.primary |
| 34 |
|
| 35 |
# Find |
| 36 |
find_keyword = { fg = "@{status.warning}", bold = true } # status.warning |
| 37 |
find_position = { fg = "@{status.success}", bold = true } # status.success |
| 38 |
|
| 39 |
# Symlink |
| 40 |
symlink_target = { italic = true } |
| 41 |
|
| 42 |
# Marker |
| 43 |
marker_copied = { fg = "@{status.warning}", bg = "@{status.warning}" } |
| 44 |
marker_cut = { fg = "@{status.danger}", bg = "@{status.danger}" } |
| 45 |
marker_marked = { fg = "@{status.info}", bg = "@{status.info}" } |
| 46 |
marker_selected = { fg = "@{status.success}", bg = "@{status.success}" } |
| 47 |
|
| 48 |
# Count |
| 49 |
count_copied = { fg = "@{surface.raised}", bg = "@{status.warning}" } |
| 50 |
count_cut = { fg = "@{surface.raised}", bg = "@{status.danger}" } |
| 51 |
count_selected = { fg = "@{surface.raised}", bg = "@{status.success}" } |
| 52 |
|
| 53 |
# Border |
| 54 |
border_symbol = "│" |
| 55 |
border_style = { fg = "@{line.border}" } # line.border |
| 56 |
# : }}} |
| 57 |
|
| 58 |
# : Indicator of hovered file {{{ |
| 59 |
# Yazi's preset uses `reversed = true` here, which inverts whatever filetype |
| 60 |
# color the row already carries. Against this palette that turned the hovered |
| 61 |
# row into a dark navy block, because directories are content.secondary. Naming |
| 62 |
# the pair explicitly keeps the hover on the surface ramp. |
| 63 |
[indicator] |
| 64 |
parent = { fg = "@{content.primary}", bg = "@{border.subtle}" } # border-subtle |
| 65 |
current = { fg = "@{content.primary}", bg = "@{border.subtle}" } |
| 66 |
preview = { underline = true } |
| 67 |
# : }}} |
| 68 |
|
| 69 |
# : Tabs {{{ |
| 70 |
[tabs] |
| 71 |
active = { fg = "@{content.primary}", bg = "@{surface.raised}", bold = true } # surface.raised |
| 72 |
inactive = { fg = "@{content.muted}", bg = "@{surface.page}" } # content.muted |
| 73 |
# : }}} |
| 74 |
|
| 75 |
# : Mode {{{ |
| 76 |
[mode] |
| 77 |
normal_main = { fg = "@{content.primary}", bg = "@{surface.raised}", bold = true } |
| 78 |
normal_alt = { fg = "@{content.muted}", bg = "@{border.subtle}" } |
| 79 |
select_main = { fg = "@{surface.raised}", bg = "@{status.warning}", bold = true } |
| 80 |
select_alt = { fg = "@{status.warning}", bg = "@{border.subtle}" } |
| 81 |
unset_main = { fg = "@{surface.raised}", bg = "@{status.danger}", bold = true } |
| 82 |
unset_alt = { fg = "@{status.danger}", bg = "@{border.subtle}" } |
| 83 |
# : }}} |
| 84 |
|
| 85 |
# : Status bar {{{ |
| 86 |
[status] |
| 87 |
overall = { fg = "@{content.primary}", bg = "@{surface.raised}" } |
| 88 |
|
| 89 |
# Permissions |
| 90 |
perm_sep = { fg = "@{content.muted}" } |
| 91 |
perm_type = { fg = "@{content.secondary}" } # content.secondary |
| 92 |
perm_read = { fg = "@{status.warning}" } |
| 93 |
perm_write = { fg = "@{status.danger}" } |
| 94 |
perm_exec = { fg = "@{status.success}" } |
| 95 |
|
| 96 |
# Progress |
| 97 |
progress_label = { fg = "@{content.primary}", bold = true } |
| 98 |
progress_normal = { fg = "@{status.success}", bg = "@{border.subtle}" } |
| 99 |
progress_error = { fg = "@{status.danger}", bg = "@{border.subtle}" } |
| 100 |
# : }}} |
| 101 |
|
| 102 |
# : Picker {{{ |
| 103 |
[pick] |
| 104 |
border = { fg = "@{line.border}" } |
| 105 |
active = { fg = "@{action.primary}", bold = true } # action.primary |
| 106 |
inactive = {} |
| 107 |
# : }}} |
| 108 |
|
| 109 |
# : Input {{{ |
| 110 |
[input] |
| 111 |
border = { fg = "@{line.border}" } |
| 112 |
title = {} |
| 113 |
value = {} |
| 114 |
selected = { fg = "@{content.primary}", bg = "@{border.subtle}" } |
| 115 |
# : }}} |
| 116 |
|
| 117 |
# : Completion {{{ |
| 118 |
[cmp] |
| 119 |
border = { fg = "@{line.border}" } |
| 120 |
active = { fg = "@{content.primary}", bg = "@{border.subtle}" } |
| 121 |
inactive = {} |
| 122 |
# : }}} |
| 123 |
|
| 124 |
# : Task manager {{{ |
| 125 |
[tasks] |
| 126 |
border = { fg = "@{line.border}" } |
| 127 |
title = {} |
| 128 |
hovered = { fg = "@{action.primary}", bold = true } |
| 129 |
# : }}} |
| 130 |
|
| 131 |
# : Confirmation {{{ |
| 132 |
[confirm] |
| 133 |
border = { fg = "@{line.border}" } |
| 134 |
title = { fg = "@{action.primary}" } |
| 135 |
body = {} |
| 136 |
list = {} |
| 137 |
btn_yes = { fg = "@{surface.raised}", bg = "@{action.primary}", bold = true } |
| 138 |
btn_no = {} |
| 139 |
# : }}} |
| 140 |
|
| 141 |
# : Spotter {{{ |
| 142 |
[spot] |
| 143 |
border = { fg = "@{line.border}" } |
| 144 |
title = { fg = "@{action.primary}" } |
| 145 |
tbl_col = { fg = "@{content.secondary}" } |
| 146 |
tbl_cell = { fg = "@{content.primary}", bg = "@{border.subtle}" } |
| 147 |
# : }}} |
| 148 |
|
| 149 |
# : Notification {{{ |
| 150 |
[notify] |
| 151 |
title_info = { fg = "@{status.success}" } |
| 152 |
title_warn = { fg = "@{status.warning}" } |
| 153 |
title_error = { fg = "@{status.danger}" } |
| 154 |
# : }}} |
| 155 |
|
| 156 |
# : Which {{{ |
| 157 |
[which] |
| 158 |
mask = { bg = "@{surface.raised}" } |
| 159 |
cand = { fg = "@{status.success}" } # status.success |
| 160 |
rest = { fg = "@{content.muted}" } |
| 161 |
desc = { fg = "@{status.warning}" } |
| 162 |
separator = " " |
| 163 |
separator_style = { fg = "@{line.border}" } |
| 164 |
# : }}} |
| 165 |
|
| 166 |
# : Help menu {{{ |
| 167 |
[help] |
| 168 |
on = { fg = "@{status.warning}" } |
| 169 |
run = { fg = "@{status.success}" } |
| 170 |
desc = { fg = "@{content.muted}" } |
| 171 |
hovered = { fg = "@{content.primary}", bg = "@{border.subtle}", bold = true } |
| 172 |
footer = { fg = "@{surface.page}", bg = "@{content.secondary}" } |
| 173 |
# : }}} |
| 174 |
|
| 175 |
# : File-specific styles {{{ |
| 176 |
[filetype] |
| 177 |
rules = [ |
| 178 |
# A file's kind is a categorical distinction, not a status, so these |
| 179 |
# take the theme's category series. Akari happens to paint several |
| 180 |
# category and status intents the same, which is why the hand-written |
| 181 |
# file could reach for `status.info` here and look right; under a theme |
| 182 |
# that separates them, "archive" wanting to be the third series color |
| 183 |
# is what this actually means. |
| 184 |
# Images |
| 185 |
{ mime = "image/*", fg = "@{category.two}" }, |
| 186 |
# Videos |
| 187 |
{ mime = "video/*", fg = "@{category.four}" }, |
| 188 |
# Audio |
| 189 |
{ mime = "audio/*", fg = "@{category.five}" }, |
| 190 |
# Archives |
| 191 |
{ mime = "application/zip", fg = "@{category.three}" }, |
| 192 |
{ mime = "application/gzip", fg = "@{category.three}" }, |
| 193 |
{ mime = "application/x-tar", fg = "@{category.three}" }, |
| 194 |
{ mime = "application/x-bzip", fg = "@{category.three}" }, |
| 195 |
{ mime = "application/x-bzip2", fg = "@{category.three}" }, |
| 196 |
{ mime = "application/x-7z-compressed", fg = "@{category.three}" }, |
| 197 |
{ mime = "application/x-rar", fg = "@{category.three}" }, |
| 198 |
{ mime = "application/xz", fg = "@{category.three}" }, |
| 199 |
# PDF |
| 200 |
{ mime = "application/pdf", fg = "@{status.danger}" }, |
| 201 |
# Broken links and executables, ahead of the catch-alls |
| 202 |
{ url = "*", is = "orphan", fg = "@{status.danger}" }, |
| 203 |
{ url = "*", is = "exec", fg = "@{action.primary}" }, |
| 204 |
# Fallback |
| 205 |
{ url = "*", fg = "@{content.primary}" }, |
| 206 |
{ url = "*/", fg = "@{content.secondary}" }, # directories |
| 207 |
] |
| 208 |
# : }}} |
| 209 |
|
| 210 |
# : Icons {{{ |
| 211 |
[icon] |
| 212 |
# Deliberately empty, and this section exists only to be empty. |
| 213 |
# |
| 214 |
# Yazi ships a filetype icon set drawn from a Nerd Font's Private Use Area, and |
| 215 |
# with no `[icon]` section here it fell through to that set — which made yazi |
| 216 |
# the one live PUA consumer in the whole image, and the sole reason a 60 MB |
| 217 |
# nerd-patched font was installed at all (STACK.md#fonts, wiki |
| 218 |
# `typography-standard`). The image now ships Quasi Mono, the house face, which |
| 219 |
# carries no PUA: those icons would paint as missing glyphs. |
| 220 |
# |
| 221 |
# So: no icons rather than borrowed ones. A file's kind is already carried by |
| 222 |
# the [filetype] colours above, which is a distinction the theme owns and can |
| 223 |
# state consistently everywhere; a private-use glyph is a distinction one font |
| 224 |
# happens to draw. Max, 2026-08-16, on the Nerd Font set: "frankly most of those |
| 225 |
# are awful". |
| 226 |
# |
| 227 |
# All five rule lists are named, empty, rather than the section being omitted. |
| 228 |
# Yazi merges what a theme does not mention, so an omitted list is the preset's |
| 229 |
# list and a present-and-empty one is ours. |
| 230 |
globs = [] |
| 231 |
dirs = [] |
| 232 |
files = [] |
| 233 |
exts = [] |
| 234 |
conds = [] |
| 235 |
# : }}} |
| 236 |
|