Skip to content

Theme customization

Thiago Lucio edited this page Nov 1, 2026 · 1 revision

Customizing themes is easy. You have two options: add the new theme at ~/.local/share/flux/themes/new-theme.css or customize through ~/.config/flux/style.css.

For full details, read style.css

/* Flux style overrides.
 *
 * Every selector Flux uses is listed below with a comment explaining what
 * it styles and which properties are worth changing. The rules are empty
 * on purpose: Flux ships a default theme compiled into the binary, and
 * anything you write here is loaded on top of it. Fill in a rule to
 * override that part of the default look; leave it empty to keep it.
 *
 * The full default theme (with current values) is at:
 *   /usr/share/flux/style.css
 * Use it as a reference for what a selector currently sets.
 */

/* ── Window and background ─────────────────────────────────────────── */

/* Root window and the app background. Change the base background color. */
window,
window > box,
.background {
}

/* Header bar. Background, padding, title weight. */
headerbar {
}

/* Window title label inside the header bar. */
headerbar > windowtitle label.title {
}

/* Any label inside the header bar (includes the title). */
headerbar label {
}

/* Header bar buttons, toggles and menus (back/forward, menu, search). */
headerbar button,
headerbar togglebutton,
headerbar menubutton {
}

/* Header bar button hover. */
headerbar button:hover,
headerbar togglebutton:hover,
headerbar menubutton:hover {
}

/* Header bar button icon size. */
headerbar button image,
headerbar togglebutton image,
headerbar menubutton image,
headerbar .image-button image {
}

/* Header bar toggle in the pressed/checked state (e.g. search active). */
headerbar togglebutton:checked,
headerbar togglebutton:active {
}

/* Window controls (minimize, maximize, close). */
windowcontrols button {
}

/* Close button hover — currently tints red. */
windowcontrols button.close:hover {
}

/* ── Sidebar ───────────────────────────────────────────────────────── */

/* Sidebar container. */
.flux-sidebar-root {
}

/* A regular (non-section) sidebar row. Change radius, padding, hover motion. */
.sidebar-row:not(.sidebar-section) {
}

/* The label inside a sidebar row. */
.sidebar-row:not(.sidebar-section) label {
}

/* Sidebar row hover (not selected). */
.sidebar-row:not(.sidebar-section):hover:not(:selected) {
}

/* The currently selected sidebar row. */
.sidebar-row:not(.sidebar-section):selected {
}

/* Section header rows ("Places", "Devices", "Network"). */
.sidebar-section {
}

/* The small uppercase label above each section. */
.sidebar-section-label {
}

/* Mounted device row. */
.sidebar-mount {
}

/* Eject button on a mount row. */
button.eject-button {
}

/* Pin drop zone shown while dragging. */
.sidebar-pin-zone {
}

/* ── Breadcrumbs ───────────────────────────────────────────────────── */

/* A breadcrumb button (each path segment). */
button.breadcrumb-btn {
}

/* The last breadcrumb (current directory) — normally accent-colored. */
button.breadcrumb-btn:last-child {
}

/* Breadcrumb hover (not the current segment). */
button.breadcrumb-btn:hover:not(:last-child) {
}

/* ── File grid / list ──────────────────────────────────────────────── */

/* The grid or list view. Background and padding. */
gridview,
listview {
}

/* A file card in the grid view. */
.flux-card {
}

/* File card hover. */
.flux-card:hover {
}

/* File name label under a card. */
.flux-label {
}

/* Selected file card. */
gridview child:selected .flux-card {
}

/* Empty-directory marker. */
.flux-card.flux-card--empty {
}

/* Symlink marker. */
.flux-card.flux-card--symlink {
}

/* Broken symlink marker. */
.flux-card.flux-card--broken-symlink {
}

/* Card that is cut (pending move). */
.flux-card.flux-card--cut {
}

/* Card that is copied (pending copy). */
.flux-card--copy {
}

/* Lock badge on files owned by another user. */
.flux-lock-badge {
}

/* The "N items · 4.2 MB" info pill shown on selected cards. */
.flux-list-info {
}

/* Rename-in-place entry inside a card. */
entry.flux-rename-entry {
}

/* ── Git badges ────────────────────────────────────────────────────── */

/* Base style for all git status badges. */
.flux-git-badge {
}

/* Untracked file badge. */
.flux-git-untracked {
}

/* Added file badge. */
.flux-git-added {
}

/* Modified file badge. */
.flux-git-modified,
.flux-git-mixed {
}

/* Staged file badge. */
.flux-git-staged {
}

/* Deleted file badge. */
.flux-git-deleted {
}

/* Conflicted file badge. */
.flux-git-conflict {
}

/* ── Filter bar ────────────────────────────────────────────────────── */

/* The filter bar shown when a filter is active. */
.flux-filter-bar {
}

/* The filter chip ("filter: *.rs"). */
.flux-filter-chip {
}

/* ── Search ────────────────────────────────────────────────────────── */

/* The search icon inside the search panel. */
.search-panel-icon {
}

/* ── Selection status bar ──────────────────────────────────────────── */

/* The whole status bar at the bottom of the window. */
.selection-status {
}

/* The caption label ("3 items selected"). */
.selection-status label.caption {
}

/* The progress bar inside the status bar (shown during tasks). */
.selection-status progressbar {
}

/* Progress bar fill. */
.selection-status progressbar progress {
}

/* A flat button inside the status bar (navigate chip, clear selection). */
.selection-status button.flat {
}

/* The "navigate" chip shown when a search hit is selected. */
.selection-status button.navigate-chip {
}

/* The destructive "Delete" button in the status bar. */
.selection-status button.destructive-action {
}

/* ── Quick panel (bottom dock) ─────────────────────────────────────── */

/* The quick-panel container. */
.quick-panel {
}

/* A quick-panel tab / button. */
.quick-panel-tab {
}

/* The checked (active) tab. */
.quick-panel-tab:checked,
.quick-panel-tab.suggested-action {
}

/* ── Popovers and menus ────────────────────────────────────────────── */

/* Popover background. */
popover.menu contents,
popover.background contents {
}

/* A menu item (modelbutton). */
popover.menu modelbutton {
}

/* Menu item hover. */
popover.menu modelbutton:hover {
}

/* Separator between menu groups. */
popover.menu > contents separator {
}

/* ── Entries ───────────────────────────────────────────────────────── */

/* Any text entry. */
entry,
searchentry,
passwordentry {
}

/* Entry in the focused state. */
entry:focus,
searchentry:focus,
passwordentry:focus {
}

/* ── Buttons and general controls ──────────────────────────────────── */

/* The default suggested-action button (accent-colored). */
.suggested-action {
}

/* The destructive-action button. */
.destructive-action {
}

/* Flat button (no background). */
.flat {
}

/* A pill-shaped button. */
.pill {
}

/* A circular icon button. */
.circular {
}

/* ── Tabs ──────────────────────────────────────────────────────────── */

/* A tab in the tab bar. */
tabbar tab {
}

/* The active/selected tab. */
tabbar tab:checked,
tabbar tab:selected,
tabbar tab.selected {
}

/* The tab label. */
tabbar tab label {
}

/* ── Toasts ────────────────────────────────────────────────────────── */

/* A toast notification. */
toast {
}

/* The toast message label. */
toast label {
}

/* A button inside a toast (e.g. "Undo"). */
toast button {
}

/* ── Typography helpers ────────────────────────────────────────────── */

/* Large heading (dialog titles). */
.title-1 {
}

/* Medium heading (section titles). */
.title-3 {
}

/* Emphasized accent text (counts, active values). */
.accent {
}

/* Monospace numeric label (sizes, item counts). */
.numeric {
}

/* Monospace text. */
.monospace {
}

/* ── Error / warning / success ─────────────────────────────────────── */

/* Error banner. */
.error {
}

/* Warning banner. */
.warning {
}

/* Success text. */
.success {
}

/* ── Misc ──────────────────────────────────────────────────────────── */

/* Keycap ("Ctrl") label used in menus and the help window. */
.keycap {
}

/* Preview pane navigation buttons (prev/next). */
.preview-nav-btn image {
}

/* Archive badge shown on an archive file. */
.flux-archive-badge {
}

/* Lock hint shown on a LUKS-encrypted image. */
.flux-lock-hint {
}

/* Run button on a custom action row. */
.flux-action-run-btn {
}

/* Tooltip background. */
tooltip.background {
}

Theme example: this theme is meant to apply a blur effect, generally, some compositors support that.

/* Veil - a complete standalone theme.
 *
 * This file overrides GTK's @theme_*, @window_*, @popover_*, @accent_* and
 * @destructive_* named colors. Do not combine it with inherits = "default":
 * the default theme's :root reads those names, and the result depends on
 * load order.
 *
 * Dark-only (variant = "dark"). Widgets not styled here follow the system
 * appearance, so on a light desktop some widgets will look inconsistent.
 *
 * The --nt-* variables are this theme's own vocabulary, not Flux's API.
 * rgba(..., calc(...)) requires GTK 4.16+, older GTK ignores those lines
 * and falls back to the veil variables.
 */

:root {
  --nt-alpha: 0.55;
  --nt-lift: 0.1;
  --nt-veil-rgb: 42, 42, 42;
}

@define-color nt_white       #ffffff;
@define-color nt_gray_050    #ededed;
@define-color nt_gray_100    #d6d6d6;
@define-color nt_gray_200    #bababa;
@define-color nt_gray_300    #9e9e9e;
@define-color nt_gray_400    #808080;
@define-color nt_gray_500    #646464;
@define-color nt_gray_600    #4a4a4a;
@define-color nt_gray_700    #3a3a3a;
@define-color nt_gray_800    #2a2a2a;
@define-color nt_gray_900    #1c1c1c;
@define-color nt_black       #0e0e0e;

@define-color window_bg_color      rgba(37, 37, 37, 0.55);
@define-color window_fg_color      @nt_gray_050;
@define-color view_bg_color        transparent;
@define-color view_fg_color        @nt_gray_050;
@define-color headerbar_bg_color   transparent;
@define-color headerbar_fg_color   @nt_gray_050;
@define-color sidebar_bg_color     transparent;
@define-color sidebar_fg_color     @nt_gray_050;
@define-color card_bg_color        transparent;
@define-color card_fg_color        @nt_gray_050;
@define-color dialog_bg_color      rgba(37, 37, 37, 0.55);
@define-color dialog_fg_color      @nt_gray_050;
@define-color popover_bg_color     rgba(32, 32, 32, 0.60);
@define-color popover_fg_color     @nt_gray_050;
@define-color theme_fg_color       @nt_gray_050;
@define-color theme_bg_color       rgba(37, 37, 37, 0.55);
@define-color theme_base_color     transparent;
@define-color theme_text_color     @nt_gray_050;

@define-color accent_color         rgba(255, 255, 255, 0.55);
@define-color accent_bg_color      rgba(255, 255, 255, 0.35);
@define-color accent_fg_color      @nt_white;

@define-color destructive_color    #d6a0a0;
@define-color destructive_bg_color rgba(214, 160, 160, 0.35);
@define-color destructive_fg_color @nt_white;

:root {
  --border-color: alpha(@nt_white, 0.16);
  --disabled-opacity: 0.4;
  --shadow: rgba(0, 0, 0, 0.35);
  --shadow-hover: rgba(0, 0, 0, 0.5);
  --font-main: "Inter", "Helvetica Neue", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", "Fira Code", monospace;

  --color-fg: @nt_gray_050;
  --color-window-bg: rgba(var(--nt-veil-rgb), var(--nt-alpha));
  --color-window-fg: @nt_gray_050;
  --color-card-bg: transparent;
  --color-sidebar-bg: transparent;
  --color-popover-bg: rgba(var(--nt-veil-rgb), calc(var(--nt-alpha) + 0.05));
  --color-popover-fg: @nt_gray_050;
  --color-headerbar-bg: transparent;
  --color-headerbar-fg: @nt_gray_050;

  --color-accent: rgba(255, 255, 255, 0.55);
  --color-accent-fg: @nt_white;
  --color-accent-text: @nt_gray_100;

  --color-danger: #d6a0a0;
  --color-warn: #d6c8a0;
  --color-success: #a0d6a8;
  --color-git-mod: #9e9e9e;
  --color-git-staged: #bababa;
  --color-git-untracked: #808080;

  letter-spacing: 0px;
}

window,
window > box,
.background,
window.background {
  background-color: var(--color-window-bg);
  background-image: linear-gradient(
    rgba(0, 0, 0, var(--nt-lift)),
    rgba(0, 0, 0, var(--nt-lift))
  );
  color: var(--color-window-fg);
}

window.csd,
window.solid-csd {
  background-color: var(--color-window-bg);
  background-image: linear-gradient(
    rgba(0, 0, 0, var(--nt-lift)),
    rgba(0, 0, 0, var(--nt-lift))
  );
  box-shadow: none;
}

toolbarview,
toolbarview > .top-bar,
toolbarview > .bottom-bar,
toolbarview > .top-bar > windowcontrols,
toolbarview > .bottom-bar > windowcontrols {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
}

headerbar {
  background-color: transparent;
  background-image: none;
  box-shadow: none;
  border: none;
}

.sidebar,
.flux-sidebar-root,
.sidebar-inner {
  background-color: transparent;
  background-image: none;
}

.sidebar scrolledwindow,
.sidebar viewport,
.sidebar list,
.sidebar listview {
  background-color: transparent;
  background-image: none;
}

.sidebar-row:not(.sidebar-section) {
  background-color: transparent;
}

.sidebar-row:not(.sidebar-section):hover:not(:selected) {
  background-color: alpha(@nt_white, 0.08);
}

.sidebar-row:not(.sidebar-section):selected {
  background-color: alpha(@nt_white, 0.18);
}

.sidebar-section,
.sidebar-section-label {
  background-color: transparent;
  background-image: none;
}

gridview,
listview,
.view {
  background-color: transparent;
  background-image: none;
}

gridview,
listview {
  border-radius: 1.1em;
}

.flux-card {
  background-color: transparent;
  border: 1px solid var(--border-color);
  box-shadow: none;
  transition:
    background-color 150ms ease,
    border-color 150ms ease;
}

.flux-card:hover {
  background-color: transparent;
  border-color: alpha(@nt_white, 0.26);
}

gridview child:selected .flux-card {
  background-color: transparent;
  border-color: alpha(@nt_white, 0.42);
  box-shadow: inset 0 0 0 1px alpha(@nt_white, 0.42);
}

popover,
popover.background,
popover.menu {
  background-color: transparent;
  background-image: none;
  border: none;
  outline: none;
  box-shadow: none;
  padding: 0px;
}

popover.menu contents,
popover.background contents {
  background-color: var(--color-popover-bg);
  background-image: linear-gradient(
    rgba(0, 0, 0, var(--nt-lift)),
    rgba(0, 0, 0, var(--nt-lift))
  );
  border: 1px solid var(--border-color);
  border-radius: 12px;
  outline: none;
  box-shadow: none;
  padding: 4px;
}

popover.menu > arrow,
popover.background > arrow {
  background-color: var(--color-popover-bg);
  border: 1px solid var(--border-color);
  box-shadow: none;
}

popover.menu modelbutton {
  background: transparent;
  border: none;
  box-shadow: none;
  color: @nt_gray_050;
  min-height: 28px;
  padding: 4px 8px;
  border-radius: 6px;
}

popover.menu modelbutton label {
  color: @nt_gray_050;
  font-weight: 500;
}

popover.menu modelbutton:hover {
  background-color: alpha(@nt_white, 0.12);
  color: @nt_white;
}

popover.menu modelbutton:hover label,
popover.menu modelbutton:hover accelerator,
popover.menu modelbutton:hover .accelerator,
popover.menu modelbutton:hover image,
popover.menu modelbutton:hover arrow {
  color: @nt_white;
}

popover.menu > contents separator {
  background-color: alpha(@nt_white, 0.1);
  min-height: 1px;
  margin: 4px 8px;
}

toast {
  background-color: var(--color-popover-bg);
  border: 1px solid var(--border-color);
  border-radius: 0.9em;
  box-shadow: none;
}

toast label {
  color: var(--color-window-fg);
}

.selection-status {
  font-size: 1em;
  background-color: transparent;
  padding: 0.45em 1.2em;
  min-height: 2.2em;
}

.quick-panel-scroll {
  background: none;
  border: none;
  box-shadow: none;
}

.quick-panel {
  background-color: var(--color-popover-bg);
  border: 1px solid var(--border-color);
  border-radius: 0.9em;
  box-shadow: none;
}

.quick-panel button,
.quick-panel-tab {
  background-color: transparent;
  border: 1px solid var(--border-color);
  border-radius: 0.6em;
  color: @nt_gray_050;
}

.quick-panel button label,
.quick-panel-tab label {
  color: @nt_gray_050;
}

.quick-panel button:hover:not(:checked):not(:active):not(.suggested-action),
.quick-panel-tab:hover:not(:checked):not(:active):not(.suggested-action) {
  background-color: alpha(@nt_white, 0.1);
}

.quick-panel button:checked,
.quick-panel button.suggested-action,
.quick-panel-tab:checked,
.quick-panel-tab.suggested-action {
  background-color: alpha(@nt_white, 0.2);
  border-color: alpha(@nt_white, 0.4);
  color: @nt_white;
}

.quick-panel button:checked label,
.quick-panel button.suggested-action label,
.quick-panel-tab:checked label,
.quick-panel-tab.suggested-action label {
  color: @nt_white;
  font-weight: 700;
}

entry,
searchentry,
passwordentry {
  background-color: transparent;
  border: 1px solid var(--border-color);
  color: @nt_gray_050;
  caret-color: @nt_gray_050;
}

entry placeholder,
searchentry placeholder,
passwordentry placeholder {
  color: alpha(@nt_gray_050, 0.55);
}

entry:focus,
searchentry:focus,
passwordentry:focus {
  box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.25);
}

.selection-status button.flat {
  background-color: transparent;
  border: 1px solid var(--border-color);
  color: alpha(@nt_gray_050, 0.85);
}

.selection-status button.flat:hover {
  background-color: alpha(@nt_white, 0.12);
  color: @nt_white;
}

.selection-status button.destructive-action {
  background-color: transparent;
  border: 1px solid alpha(@destructive_color, 0.5);
  color: @destructive_color;
}

.selection-status button.destructive-action:hover {
  background-color: alpha(@destructive_color, 0.2);
  color: @nt_white;
}

.suggested-action {
  background-color: rgba(255, 255, 255, 0.55);
  color: @nt_black;
  border: none;
}

.suggested-action:hover {
  background-color: rgba(255, 255, 255, 0.7);
}

.destructive-action {
  background-color: rgba(214, 160, 160, 0.55);
  color: @nt_white;
}

.destructive-action:hover {
  background-color: rgba(214, 160, 160, 0.7);
  color: @nt_white;
}

Clone this wiki locally