Skip to content

Example Three Kernel Desk

locainin edited this page Feb 13, 2026 · 1 revision

Example Three (Kernel Desk)

Example Three

This page contains the exact active local configuration and theme overrides used for the screenshot above.

It includes all runtime files required for this setup, including custom widget scripts referenced by config.toml.

config.toml
rules = []

[general]
dnd_default = false

[inhibit]
mode = "no_popups"

[popups]
anchor = "top-right"
width = 372
spacing = 12
max_visible = 4
default_timeout_ms = 5000
allow_click_through = false

[popups.margin]
top = 14
right = 14
bottom = 14
left = 14

[panel]
anchor = "right"
width = 420
height = 0
keyboard_interactivity = "on-demand"
empty_text = "0x0000 EVENT QUEUE EMPTY"
empty_offset_top = 98
close_on_blur = false
close_on_click_outside = true
respect_work_area = true

[panel.margin]
top = 16
right = 10
bottom = 14
left = 10

[history]
max_entries = 200
max_active = 500
transient_to_history = false

[media]
enabled = true
include_browsers = true
browser_tokens = [
    "firefox",
    "librewolf",
    "waterfox",
    "floorp",
    "brave",
    "chromium",
    "chrome",
    "vivaldi",
    "edge",
    "opera",
    "epiphany",
    "midori",
    "zen",
]
title_char_limit = 32
allowlist = []
denylist = ["playerctld"]

[widgets]
refresh_interval_ms = 1400
refresh_interval_slow_ms = 4200

[widgets.volume]
enabled = true
label = "Volume"
icon = "audio-volume-high-symbolic"
icon_muted = "audio-volume-muted-symbolic"
get_cmd = "wpctl get-volume @DEFAULT_AUDIO_SINK@"
set_cmd = "wpctl set-volume @DEFAULT_AUDIO_SINK@ {value}%"
toggle_cmd = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"
min = 0.0
max = 100.0
step = 1.0
parse_mode = "auto"

[widgets.brightness]
enabled = true
label = "Brightness"
icon = "display-brightness-symbolic"
get_cmd = "brightnessctl -m"
set_cmd = "brightnessctl s {value}%"
watch_cmd = "brightnessctl -w"
min = 0.0
max = 100.0
step = 1.0
parse_mode = "auto"

[[widgets.toggles]]
enabled = true
kind = "wifi"
label = "Wi-Fi"
icon = "network-wireless-signal-excellent-symbolic"
state_cmd = "nmcli radio wifi"
on_cmd = "nmcli radio wifi on"
off_cmd = "nmcli radio wifi off"
watch_cmd = "nmcli -t monitor"

[[widgets.toggles]]
enabled = true
kind = "bluetooth"
label = "Bluetooth"
icon = "bluetooth-active-symbolic"
state_cmd = "bluetoothctl show"
on_cmd = "bluetoothctl power on"
off_cmd = "bluetoothctl power off"
watch_cmd = "dbus-monitor --system type=signal,sender=org.bluez"

[[widgets.toggles]]
enabled = true
kind = "airplane"
label = "Airplane"
icon = "airplane-mode-symbolic"
state_cmd = """rfkill list all | awk '/Soft blocked:/ { seen=1; if ($3 != "yes") bad=1 } END { exit (seen && !bad) ? 0 : 1 }'"""
on_cmd = "rfkill block all"
off_cmd = "rfkill unblock all"
watch_cmd = "udevadm monitor --udev --subsystem-match=rfkill"

[[widgets.toggles]]
enabled = true
kind = "night"
label = "Night"
icon = "weather-clear-night-symbolic"
state_cmd = "pgrep -x gammastep >/dev/null 2>&1"
on_cmd = "nohup gammastep -m wayland -l 0:0 -t 4500:4500 -P >/dev/null 2>&1 &"
off_cmd = "pkill -x gammastep >/dev/null 2>&1; gammastep -x >/dev/null 2>&1"

[[widgets.stats]]
enabled = true
label = "CPU"
icon = "utilities-system-monitor-symbolic"
cmd = "builtin:cpu"
min_height = 56

[[widgets.stats]]
enabled = true
label = "RAM"
icon = "drive-harddisk-symbolic"
cmd = "builtin:memory"
min_height = 56

[[widgets.stats]]
enabled = true
label = "Battery"
icon = "battery-full-symbolic"
cmd = "builtin:battery"
min_height = 56

[[widgets.stats]]
enabled = true
label = "Load"
icon = "view-statistics-symbolic"
cmd = "builtin:load"
min_height = 56

[[widgets.stats]]
enabled = true
label = "Net Flux"
icon = "network-transmit-receive-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-net-rate-stat | jq -r .text'"""
min_height = 56

[[widgets.stats]]
enabled = true
label = "Thermal"
icon = "temperature-high-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-thermal-stat | jq -r .text'"""
min_height = 56

[[widgets.cards]]
enabled = true
kind = "custom"
title = "Kernel Pulse"
subtitle = "runtime telemetry"
icon = "applications-system-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-creative-status | jq -r .text'"""
min_height = 112
monospace = true

[[widgets.cards]]
enabled = false
kind = "custom"
title = "Storage Map"
subtitle = "filesystem telemetry"
icon = "drive-harddisk-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-storage-card | jq -r .text'"""
min_height = 112
monospace = true

[[widgets.cards]]
enabled = false
kind = "custom"
title = "Hot Process"
subtitle = "top scheduler entry"
icon = "utilities-system-monitor-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-process-card | jq -r .text'"""
min_height = 112
monospace = true

[[widgets.cards]]
enabled = true
kind = "custom"
title = "Toolchain"
subtitle = "compiler snapshot"
icon = "text-x-csrc-symbolic"
cmd = """sh -c '${XDG_CONFIG_HOME:-$HOME/.config}/unixnotis/scripts/unixnotis-toolchain-card'"""
min_height = 112
monospace = true

[sound]
enabled = true
default_name = "message-new-instant"

[theme]
base_css = "base.css"
popup_css = "popup.css"
panel_css = "panel.css"
widgets_css = "widgets.css"
border_width = 2
card_radius = 4
surface_alpha = 0.94
surface_strong_alpha = 0.98
card_alpha = 0.96
shadow_soft_alpha = 0.46
shadow_strong_alpha = 0.72
base.css
/* UnixNotis base theme: Kernel Desk */

/* Foundation surfaces */
@define-color unixnotis-surface-base #090b10;
@define-color unixnotis-surface-strong-base #11151c;
@define-color unixnotis-card-base #171d27;

/* Runtime alpha hooks */
@define-color unixnotis-surface alpha(@unixnotis-surface-base, 0.90);
@define-color unixnotis-surface-strong alpha(@unixnotis-surface-strong-base, 0.94);
@define-color unixnotis-surface-soft alpha(#202939, 0.84);
@define-color unixnotis-card alpha(@unixnotis-card-base, 0.92);

/* Typography */
@define-color unixnotis-text #d9e2ef;
@define-color unixnotis-muted #8595ab;

/* Accent system */
@define-color unixnotis-accent #ffbf66;
@define-color unixnotis-accent-2 #86b4ff;
@define-color unixnotis-urgent #ff4b68;

/* Per-toggle accents */
@define-color unixnotis-accent-wifi #5fd6a3;
@define-color unixnotis-accent-bluetooth #86b4ff;
@define-color unixnotis-accent-airplane #ffbf66;
@define-color unixnotis-accent-night #ad9fe8;

/* Border + elevation */
@define-color unixnotis-card-border alpha(#9aabc6, 0.30);
@define-color unixnotis-outline alpha(#adbed6, 0.38);
@define-color unixnotis-shadow-soft alpha(#02060b, 0.46);
@define-color unixnotis-shadow-strong alpha(#02060b, 0.72);
@define-color unixnotis-glass-shine alpha(#ffffff, 0.15);
@define-color unixnotis-glass-sheen alpha(#ffffff, 0.04);
@define-color unixnotis-glass-depth alpha(#000000, 0.18);

/* Glow helpers */
@define-color unixnotis-glow-cyan alpha(@unixnotis-accent, 0.22);
@define-color unixnotis-glow-pink alpha(@unixnotis-accent-2, 0.18);
@define-color unixnotis-glow-violet alpha(@unixnotis-accent-night, 0.20);
@define-color unixnotis-glow-wifi alpha(@unixnotis-accent-wifi, 0.24);
@define-color unixnotis-glow-bluetooth alpha(@unixnotis-accent-bluetooth, 0.24);
@define-color unixnotis-glow-airplane alpha(@unixnotis-accent-airplane, 0.24);
@define-color unixnotis-glow-night alpha(@unixnotis-accent-night, 0.22);

/* Shared gradients */
@define-color unixnotis-panel-grad-1 alpha(#0b0d13, 0.98);
@define-color unixnotis-panel-grad-2 alpha(#121722, 0.99);
@define-color unixnotis-panel-grad-3 alpha(#1b2230, 1.0);

@define-color unixnotis-notification-bg-1 alpha(#151b27, 0.98);
@define-color unixnotis-notification-bg-2 alpha(#101622, 0.98);

@define-color unixnotis-popup-bg-1 #151b27;
@define-color unixnotis-popup-bg-2 #101622;

@define-color unixnotis-pill-bg #1c2432;
@define-color unixnotis-pill-border #3f536f;
@define-color unixnotis-pill-hover #273247;

@define-color unixnotis-action-bg alpha(#182130, 0.98);
@define-color unixnotis-action-bg-hover alpha(#24334c, 0.98);
@define-color unixnotis-action-bg-active alpha(#334765, 0.92);

@define-color unixnotis-popup-action-bg alpha(#182130, 0.98);
@define-color unixnotis-popup-action-hover alpha(#24334c, 0.98);
@define-color unixnotis-popup-action-active alpha(#334765, 0.92);

/* Global window defaults */
.unixnotis-panel-window,
.unixnotis-popup-window {
  background: transparent;
  color: @unixnotis-text;
  font-family: "Iosevka Term", "JetBrains Mono", "CaskaydiaCove Nerd Font Mono", "Noto Sans Mono", monospace;
}
panel.css
/* UnixNotis panel theme: Kernel Desk */
.unixnotis-panel {
  background-image:
    radial-gradient(circle at 18% -12%, alpha(#ffffff, 0.18), transparent 46%),
    linear-gradient(178deg, @unixnotis-glass-shine 0%, @unixnotis-glass-sheen 16%, alpha(#ffffff, 0.01) 38%, @unixnotis-glass-depth 100%),
    linear-gradient(160deg, @unixnotis-panel-grad-1 0%, @unixnotis-panel-grad-2 58%, @unixnotis-panel-grad-3 100%),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.08), alpha(#9aa8be, 0.08) 1px, transparent 1px, transparent 14px);
  color: @unixnotis-text;
  border-radius: 9px;
  padding: 12px;
  border: 2px solid alpha(@unixnotis-outline, 0.78);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(#aab3c1, 0.08),
    0 26px 46px -26px @unixnotis-shadow-strong,
    0 12px 24px -16px @unixnotis-shadow-soft;
}


.unixnotis-panel-header {
  margin-bottom: 10px;
  padding: 8px 9px;
  border-radius: 5px;
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.02) 42%, alpha(#000000, 0.08) 100%),
    linear-gradient(150deg, alpha(@unixnotis-surface-strong, 0.97), alpha(@unixnotis-surface-soft, 0.96));
  border: 1px solid alpha(@unixnotis-outline, 0.58);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    0 8px 16px -14px @unixnotis-shadow-soft;
}

.unixnotis-panel-header-top {
  min-height: 32px;
}

.unixnotis-panel-title-stack {
  min-width: 0;
}

.unixnotis-panel-title-row {
  min-height: 30px;
}

.unixnotis-panel-title {
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.unixnotis-panel-count {
  background-image: linear-gradient(130deg, alpha(@unixnotis-accent, 0.28), alpha(@unixnotis-accent-2, 0.20));
  color: @unixnotis-text;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.10em;
  border-radius: 3px;
  padding: 1px 7px;
  border: 1px solid alpha(@unixnotis-accent, 0.52);
  min-width: 26px;
  box-shadow: inset 0 0 0 1px alpha(@unixnotis-accent, 0.12);
}

.unixnotis-panel-actions {
  border-radius: 4px;
  margin-top: 4px;
}

.unixnotis-panel-action-group {
  border-radius: 4px;
}

.unixnotis-panel-action {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.11) 0%, alpha(#ffffff, 0.02) 38%, alpha(#000000, 0.07) 100%),
    linear-gradient(150deg, @unixnotis-action-bg, alpha(@unixnotis-surface, 0.88));
  color: @unixnotis-text;
  border-radius: 3px;
  padding: 4px 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.6);
  min-height: 26px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.07),
    0 6px 12px -10px @unixnotis-shadow-soft;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}

.unixnotis-panel-action-focus,
.unixnotis-panel-action-muted {
  /* Keep compact labels readable while honoring fixed panel width. */
  min-width: 86px;
}

.unixnotis-panel-action-primary {
  /* DND text is intentionally short ("DND") to cap horizontal growth. */
  min-width: 78px;
}

.unixnotis-panel-action-search {
  /* Search toggle is icon-only; expanded search input is revealed below. */
  min-width: 32px;
}

.unixnotis-panel-action-with-icon {
  padding-left: 9px;
  padding-right: 9px;
}

.unixnotis-panel-action-content {
  min-height: 15px;
}

.unixnotis-panel-action-glyph {
  min-width: 12px;
  min-height: 12px;
}

.unixnotis-panel-action-label {
  font-weight: 600;
  letter-spacing: 0.02em;
  font-size: 10px;
}

.unixnotis-panel-action:hover {
  background-image: linear-gradient(150deg, @unixnotis-action-bg-hover, alpha(@unixnotis-surface-strong, 0.76));
  border-color: alpha(@unixnotis-accent, 0.58);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.10),
    0 8px 14px -10px @unixnotis-shadow-soft;
}

.unixnotis-panel-action:checked {
  background-image: linear-gradient(140deg, alpha(@unixnotis-accent, 0.28), alpha(@unixnotis-accent-2, 0.22));
  border-color: alpha(@unixnotis-accent, 0.74);
  color: @unixnotis-text;
  box-shadow: inset 0 0 0 1px alpha(@unixnotis-accent, 0.14);
}

.unixnotis-panel-action:checked .unixnotis-panel-action-glyph,
.unixnotis-panel-action:checked .unixnotis-panel-action-label {
  color: @unixnotis-text;
}

.unixnotis-panel-action-icon {
  min-width: 26px;
  min-height: 26px;
  padding: 0;
}

.unixnotis-panel-action-close {
  margin-left: 6px;
  background-image: linear-gradient(150deg, alpha(@unixnotis-surface-strong, 0.96), alpha(@unixnotis-surface, 0.9));
  border-color: alpha(@unixnotis-outline, 0.64);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    0 6px 12px -10px @unixnotis-shadow-soft;
}

.unixnotis-panel-action-close:hover {
  background-image: linear-gradient(150deg, alpha(@unixnotis-action-bg-hover, 0.9), alpha(@unixnotis-surface-strong, 0.84));
  border-color: alpha(@unixnotis-accent, 0.44);
}

.unixnotis-panel-search-revealer {
  margin-top: 2px;
}

.unixnotis-panel-search {
  min-height: 28px;
  border-radius: 3px;
  background-image: linear-gradient(150deg, alpha(@unixnotis-surface, 0.94), alpha(@unixnotis-surface-soft, 0.8));
  border: 1px solid alpha(@unixnotis-outline, 0.62);
  padding: 0 8px;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.07);
}

.unixnotis-panel-search:focus-within {
  border-color: alpha(@unixnotis-accent, 0.62);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    0 0 18px -12px @unixnotis-glow-cyan;
}

.unixnotis-panel-close,
.unixnotis-popup-close {
  background: alpha(@unixnotis-surface-strong, 0.98);
  color: @unixnotis-text;
  border-radius: 3px;
  border: 1px solid alpha(@unixnotis-outline, 0.64);
  padding: 2px;
  min-width: 24px;
  min-height: 24px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    0 6px 12px -10px @unixnotis-shadow-soft;
}

.unixnotis-panel-close:hover,
.unixnotis-popup-close:hover {
  background: alpha(@unixnotis-urgent, 0.30);
  color: #ffffff;
  border-color: alpha(@unixnotis-urgent, 0.68);
}

.unixnotis-panel-list {
  background: transparent;
}

.unixnotis-panel-list row {
  background: transparent;
  padding: 0;
  margin: 0;
}

/*
 * Group headers (app pills)
 */
.unixnotis-group {
  background: transparent;
  margin-bottom: 8px;
}

.unixnotis-group-header {
  background-image: linear-gradient(135deg, @unixnotis-pill-bg, alpha(@unixnotis-pill-hover, 0.95));
  color: @unixnotis-text;
  border-radius: 3px;
  padding: 6px 10px;
  border: 1px solid @unixnotis-pill-border;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    0 8px 14px -12px @unixnotis-shadow-soft;
  outline: none;
}

.unixnotis-group-header:hover {
  background-image: linear-gradient(135deg, @unixnotis-pill-hover, alpha(@unixnotis-accent, 0.3));
}

.unixnotis-group-header:focus,
.unixnotis-group-header:active {
  outline: none;
  box-shadow:
    0 10px 18px -16px @unixnotis-shadow-soft,
    inset 0 0 0 1px alpha(#ffffff, 0.05);
}

.unixnotis-panel-list row:selected,
.unixnotis-panel-list row:focus,
.unixnotis-panel-list row:active {
  background: transparent;
  outline: none;
  box-shadow: none;
}

.unixnotis-group-title {
  font-weight: 600;
  font-size: 12px;
  letter-spacing: 0.2px;
}

.unixnotis-group-count {
  background-image: linear-gradient(140deg, alpha(@unixnotis-accent, 0.28), alpha(@unixnotis-accent-2, 0.22));
  color: @unixnotis-text;
  border-radius: 3px;
  padding: 1px 7px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.08em;
  border: 1px solid alpha(@unixnotis-accent, 0.56);
  min-width: 22px;
}

.unixnotis-group-chevron {
  color: @unixnotis-muted;
}

.unixnotis-group-cards {
  margin-top: 3px;
}

.unixnotis-group.collapsed .unixnotis-group-cards {
  margin-left: 4px;
  margin-right: 4px;
  padding-bottom: 2px;
}

.unixnotis-group.collapsed .unixnotis-panel-card {
  margin-bottom: 5px;
}

.unixnotis-group .unixnotis-panel-card {
  margin-left: 8px;
}

/*
 * Notification cards (panel)
 */
.unixnotis-panel-card {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.11) 0%, alpha(#ffffff, 0.02) 40%, alpha(#000000, 0.08) 100%),
    linear-gradient(155deg, @unixnotis-notification-bg-1 0%, @unixnotis-notification-bg-2 100%),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.07), alpha(#9aa8be, 0.07) 1px, transparent 1px, transparent 14px);
  border: 1px solid @unixnotis-card-border;
  border-radius: 4px;
  padding: 9px 10px;
  margin-bottom: 6px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-panel-card.stacked {
  box-shadow:
    0 8px 0 -4px alpha(@unixnotis-outline, 0.18),
    0 16px 0 -8px alpha(@unixnotis-outline, 0.12),
    0 12px 22px -18px @unixnotis-shadow-soft;
}

.unixnotis-stack-ghost {
  background-image:
    repeating-linear-gradient(
      135deg,
      alpha(@unixnotis-surface-soft, 0.42),
      alpha(@unixnotis-surface-soft, 0.42) 7px,
      alpha(@unixnotis-surface, 0.78) 7px,
      alpha(@unixnotis-surface, 0.78) 14px
    );
  border-radius: 3px;
  padding: 0;
  min-height: 24px;
  opacity: 0.74;
  margin-left: 12px;
  margin-right: 12px;
  margin-top: -8px;
  border: 1px dashed alpha(@unixnotis-outline, 0.4);
  box-shadow: none;
}

.unixnotis-stack-ghost-2 {
  min-height: 18px;
  opacity: 0.42;
  margin-left: 20px;
  margin-right: 20px;
  margin-top: -10px;
  box-shadow: none;
}

.unixnotis-panel-card.active {
  border-color: alpha(@unixnotis-accent, 0.78);
  box-shadow:
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.20),
    0 0 18px -12px alpha(@unixnotis-accent, 0.32);
}

.unixnotis-panel-card.critical {
  border-color: alpha(@unixnotis-urgent, 0.84);
  background-image: linear-gradient(155deg, alpha(#2a1118, 0.95), alpha(#1f0d14, 0.95));
  box-shadow:
    inset 0 0 0 1px alpha(@unixnotis-urgent, 0.26),
    0 12px 20px -16px alpha(@unixnotis-urgent, 0.35);
}

/*
 * Empty-state
 *
 * The list uses a centered overlay label; styling is kept here so the empty
 * state visually matches the rest of the panel.
 */
.unixnotis-empty {
  background: transparent;
}

.unixnotis-empty-label {
  color: alpha(@unixnotis-muted, 0.96);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: alpha(@unixnotis-surface-strong, 0.88);
  border: 1px dashed alpha(@unixnotis-outline, 0.40);
  border-radius: 3px;
  padding: 4px 8px;
}

.unixnotis-panel-app {
  color: @unixnotis-muted;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  font-size: 10px;
  font-weight: 700;
  margin-bottom: 3px;
}

.unixnotis-panel-summary {
  font-size: 14px;
  font-weight: 700;
}

.unixnotis-panel-body {
  color: alpha(@unixnotis-text, 0.94);
  font-size: 13px;
  line-height: 1.33;
  font-family: "JetBrains Mono", "Iosevka Aile", monospace;
}

.unixnotis-panel-icon {
  margin-right: 8px;
}

.unixnotis-notification-actions {
  margin-top: 4px;
}

.unixnotis-notification-action {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.11) 0%, alpha(#ffffff, 0.02) 40%, alpha(#000000, 0.07) 100%),
    linear-gradient(150deg, @unixnotis-action-bg, alpha(@unixnotis-surface, 0.92));
  color: @unixnotis-text;
  border-radius: 3px;
  padding: 4px 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.62);
  min-height: 25px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.07);
}

.unixnotis-notification-action:hover {
  background-image: linear-gradient(150deg, @unixnotis-action-bg-hover, alpha(@unixnotis-surface-strong, 0.82));
  border-color: alpha(@unixnotis-accent, 0.46);
}
popup.css
/* UnixNotis popup theme: Kernel Desk */

.unixnotis-popup-stack {
  padding: 12px;
  background: transparent;
}

.unixnotis-popup-revealer {
  margin-bottom: 8px;
  background: transparent;
}

.unixnotis-popup-card {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.03) 40%, alpha(#000000, 0.08) 100%),
    linear-gradient(155deg, @unixnotis-popup-bg-1 0%, @unixnotis-popup-bg-2 100%),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.08), alpha(#9aa8be, 0.08) 1px, transparent 1px, transparent 14px);
  color: @unixnotis-text;
  border-radius: 4px;
  border: 1px solid alpha(@unixnotis-outline, 0.74);
  padding: 13px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 14px 24px -16px @unixnotis-shadow-soft;
}

.unixnotis-popup-card.unixnotis-popup-stacked {
  box-shadow: 0 8px 16px -14px @unixnotis-shadow-soft;
  opacity: 0.95;
}

.unixnotis-popup-card.unixnotis-popup-visible {
  opacity: 1;
}

.unixnotis-popup-card.critical {
  border-color: alpha(@unixnotis-urgent, 0.86);
  background-image: linear-gradient(155deg, alpha(#2a1118, 0.96), alpha(#1f0d14, 0.96));
  box-shadow:
    inset 0 0 0 1px alpha(@unixnotis-urgent, 0.24),
    0 14px 24px -16px alpha(@unixnotis-urgent, 0.26);
}

.unixnotis-popup-header-row {
  margin-bottom: 8px;
  padding: 7px 9px;
  border-radius: 3px;
  background: alpha(@unixnotis-surface-strong, 0.72);
  border: 1px solid alpha(@unixnotis-outline, 0.42);
}

.unixnotis-popup-icon {
  color: @unixnotis-accent-2;
}

.unixnotis-popup-header {
  color: @unixnotis-muted;
  text-transform: uppercase;
  letter-spacing: 0.10em;
  font-size: 11px;
  font-weight: 700;
}

.unixnotis-popup-summary {
  color: @unixnotis-text;
  font-size: 14px;
  font-weight: 760;
  margin-top: 4px;
}

.unixnotis-popup-body {
  color: alpha(@unixnotis-text, 0.94);
  font-size: 13px;
  line-height: 1.33;
  margin-top: 6px;
  font-family: "JetBrains Mono", "Iosevka Aile", monospace;
}

.unixnotis-popup-actions {
  margin-top: 11px;
}

.unixnotis-popup-action {
  background: @unixnotis-popup-action-bg;
  color: @unixnotis-text;
  border-radius: 3px;
  border: 1px solid alpha(@unixnotis-outline, 0.62);
  padding: 6px 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  font-size: 10px;
  font-weight: 700;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.08);
}

.unixnotis-popup-action:hover {
  background: @unixnotis-popup-action-hover;
  border-color: alpha(@unixnotis-accent, 0.58);
  box-shadow: inset 0 0 0 1px alpha(@unixnotis-accent, 0.10);
}

.unixnotis-popup-action:active,
.unixnotis-popup-action:checked {
  background: linear-gradient(150deg, alpha(@unixnotis-accent, 0.28), alpha(@unixnotis-accent-2, 0.22));
  color: @unixnotis-text;
}
widgets.css
/* UnixNotis widgets + media theme
 *
 * Quick controls, toggles, stats, info cards, and media carousel.
 */
.unixnotis-quick-controls {
  margin-bottom: 5px;
}

.unixnotis-quick-slider {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.03) 40%, alpha(#000000, 0.08) 100%),
    linear-gradient(150deg, alpha(@unixnotis-surface, 0.98), alpha(@unixnotis-surface-soft, 0.94)),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.08), alpha(#9aa8be, 0.08) 1px, transparent 1px, transparent 14px);
  border-radius: 4px;
  padding: 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.68);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 8px 16px -14px @unixnotis-shadow-soft;
}

.unixnotis-quick-slider:hover {
  border-color: alpha(@unixnotis-accent, 0.60);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.10),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-quick-slider-volume {
  border-color: alpha(@unixnotis-accent, 0.35);
}

.unixnotis-quick-slider-brightness {
  border-color: alpha(@unixnotis-accent-2, 0.35);
}

.unixnotis-quick-slider-icon {
  background-image: linear-gradient(145deg, @unixnotis-pill-bg 0%, @unixnotis-pill-hover 100%);
  color: #ffffff;
  border-radius: 3px;
  border: 1px solid alpha(@unixnotis-outline, 0.62);
  padding: 4px;
  min-width: 28px;
  min-height: 28px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    0 6px 12px -10px @unixnotis-shadow-soft;
}

.unixnotis-quick-slider-icon:hover {
  background-image: linear-gradient(145deg, alpha(@unixnotis-accent, 0.85), alpha(@unixnotis-accent-2, 0.7));
  border-color: alpha(@unixnotis-accent, 0.5);
}

.unixnotis-quick-slider-value {
  color: @unixnotis-muted;
  font-size: 12px;
  letter-spacing: 0.06em;
  min-width: 34px;
  /* Alignment is controlled by the widget code (set_xalign) for GTK compatibility. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

.unixnotis-quick-slider-scale trough {
  background: alpha(#05080d, 0.72);
  border-radius: 3px;
  min-height: 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.58);
}

.unixnotis-quick-slider-scale highlight {
  background-image: linear-gradient(90deg, @unixnotis-accent 0%, @unixnotis-accent-2 100%);
  border-radius: 2px;
}

.unixnotis-quick-slider-scale slider {
  background: alpha(@unixnotis-surface-strong, 0.98);
  border-radius: 2px;
  min-width: 12px;
  min-height: 12px;
  border: 1px solid alpha(@unixnotis-outline, 0.74);
  margin: -1px;
  padding: 0;
  box-shadow: inset 0 0 0 1px alpha(#ffffff, 0.08);
}

/*
 * Toggle grid
 */
.unixnotis-toggle-section {
  margin-bottom: 3px;
}

.unixnotis-toggle-grid {
  padding: 0;
}

.unixnotis-toggle {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.03) 38%, alpha(#000000, 0.08) 100%),
    linear-gradient(165deg, alpha(@unixnotis-surface, 0.98), alpha(@unixnotis-surface-soft, 0.92)),
    repeating-linear-gradient(135deg, alpha(#9aa8be, 0.08), alpha(#9aa8be, 0.08) 4px, transparent 4px, transparent 10px);
  border-radius: 4px;
  padding: 7px 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.68);
  min-height: 56px;
  min-width: 82px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 6px 12px -10px alpha(@unixnotis-shadow-soft, 0.28);
  color: @unixnotis-muted;
}

/* Kind-specific toggle accents
 *
 * The center UI assigns a stable class: `.unixnotis-toggle-kind-<kind>`.
 * These overrides provide a distinct accent per control while preserving the
 * same layout and interaction behavior. */
.unixnotis-toggle.unixnotis-toggle-kind-wifi {
  border-color: alpha(@unixnotis-accent-wifi, 0.55);
}

.unixnotis-toggle.unixnotis-toggle-kind-bluetooth {
  border-color: alpha(@unixnotis-accent-bluetooth, 0.55);
}

.unixnotis-toggle.unixnotis-toggle-kind-airplane {
  border-color: alpha(@unixnotis-accent-airplane, 0.55);
}

.unixnotis-toggle.unixnotis-toggle-kind-night {
  border-color: alpha(@unixnotis-accent-night, 0.55);
}

.unixnotis-toggle:hover {
  background-image: linear-gradient(165deg, alpha(@unixnotis-surface, 0.98), alpha(@unixnotis-surface-soft, 0.92));
  border-color: alpha(@unixnotis-accent, 0.60);
  color: @unixnotis-text;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.10),
    0 8px 14px -10px alpha(@unixnotis-shadow-soft, 0.32);
}

.unixnotis-toggle.unixnotis-toggle-kind-wifi:hover {
  border-color: alpha(@unixnotis-accent-wifi, 0.62);
}
.unixnotis-toggle.unixnotis-toggle-kind-bluetooth:hover {
  border-color: alpha(@unixnotis-accent-bluetooth, 0.62);
}
.unixnotis-toggle.unixnotis-toggle-kind-airplane:hover {
  border-color: alpha(@unixnotis-accent-airplane, 0.62);
}
.unixnotis-toggle.unixnotis-toggle-kind-night:hover {
  border-color: alpha(@unixnotis-accent-night, 0.62);
}

.unixnotis-toggle:checked {
  color: @unixnotis-text;
  border-color: alpha(@unixnotis-accent, 0.74);
  background-image: linear-gradient(150deg, alpha(@unixnotis-accent, 0.28) 0%, alpha(@unixnotis-accent-2, 0.22) 100%);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.10),
    0 8px 16px -10px alpha(@unixnotis-shadow-soft, 0.36);
}

.unixnotis-toggle.unixnotis-toggle-kind-wifi:checked {
  background-image: linear-gradient(150deg, alpha(@unixnotis-accent-wifi, 0.28) 0%, alpha(@unixnotis-accent-wifi, 0.14) 100%);
}
.unixnotis-toggle.unixnotis-toggle-kind-bluetooth:checked {
  background-image: linear-gradient(150deg, alpha(@unixnotis-accent-bluetooth, 0.28) 0%, alpha(@unixnotis-accent-bluetooth, 0.14) 100%);
}
.unixnotis-toggle.unixnotis-toggle-kind-airplane:checked {
  background-image: linear-gradient(150deg, alpha(@unixnotis-accent-airplane, 0.30) 0%, alpha(@unixnotis-accent-airplane, 0.14) 100%);
}
.unixnotis-toggle.unixnotis-toggle-kind-night:checked {
  background-image: linear-gradient(150deg, alpha(@unixnotis-accent-night, 0.30) 0%, alpha(@unixnotis-accent-night, 0.14) 100%);
}

/* Keep outlines and depth visible when the panel is unfocused (GTK backdrop). */
.unixnotis-toggle:backdrop {
  border-color: alpha(@unixnotis-outline, 0.56);
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.62);
}

.unixnotis-toggle.unixnotis-toggle-kind-wifi:backdrop {
  border-color: alpha(@unixnotis-accent-wifi, 0.55);
}
.unixnotis-toggle.unixnotis-toggle-kind-bluetooth:backdrop {
  border-color: alpha(@unixnotis-accent-bluetooth, 0.55);
}
.unixnotis-toggle.unixnotis-toggle-kind-airplane:backdrop {
  border-color: alpha(@unixnotis-accent-airplane, 0.55);
}
.unixnotis-toggle.unixnotis-toggle-kind-night:backdrop {
  border-color: alpha(@unixnotis-accent-night, 0.55);
}

.unixnotis-toggle-icon {
  -gtk-icon-size: 16px;
  min-width: 21px;
  min-height: 21px;
  border-radius: 2px;
  border: 1px solid alpha(@unixnotis-outline, 0.58);
  background: alpha(@unixnotis-surface-strong, 0.88);
  padding: 3px;
}

.unixnotis-toggle-label {
  font-size: 11px;
  font-weight: 760;
  text-transform: uppercase;
  line-height: 1.14;
  letter-spacing: 0.04em;
}

.unixnotis-toggle:checked .unixnotis-toggle-icon {
  background: alpha(@unixnotis-surface-strong, 0.96);
  border-color: alpha(@unixnotis-accent, 0.54);
}

.unixnotis-stat-header,
.unixnotis-info-header {
  margin-bottom: 4px;
}

.unixnotis-stat-icon,
.unixnotis-info-icon {
  background: alpha(@unixnotis-surface-strong, 0.86);
  border-radius: 2px;
  padding: 3px;
  border: 1px solid alpha(@unixnotis-outline, 0.58);
  color: @unixnotis-muted;
}

/*
 * Stat grid
 */
.unixnotis-stat-section {
  margin-bottom: 3px;
}

.unixnotis-stat-grid {
  padding: 0;
}

.unixnotis-stat-card {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.02) 42%, alpha(#000000, 0.08) 100%),
    linear-gradient(155deg, alpha(@unixnotis-surface, 0.98), alpha(@unixnotis-surface-soft, 0.94)),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.07), alpha(#9aa8be, 0.07) 1px, transparent 1px, transparent 14px);
  border-radius: 4px;
  padding: 7px 8px;
  border: 1px solid alpha(@unixnotis-accent, 0.52);
  min-height: 52px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.14),
    0 0 0 1px alpha(@unixnotis-accent-2, 0.14),
    0 8px 16px -14px @unixnotis-shadow-soft;
}

.unixnotis-stat-card:hover {
  border-color: alpha(@unixnotis-accent-2, 0.68);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    inset 0 0 0 1px alpha(@unixnotis-accent-2, 0.14),
    0 0 0 1px alpha(@unixnotis-accent-2, 0.22),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-stat-card:backdrop {
  border-color: alpha(@unixnotis-accent, 0.46);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.64),
    inset 0 0 0 1px alpha(@unixnotis-accent, 0.10),
    0 8px 14px -14px @unixnotis-shadow-soft;
}

.unixnotis-stat-title {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: @unixnotis-muted;
}

.unixnotis-stat-value {
  font-size: 14px;
  font-weight: 700;
  color: @unixnotis-text;
  letter-spacing: 0.03em;
}

/*
 * Info cards
 */
.unixnotis-card-section {
  margin-top: 0;
  margin-bottom: 3px;
  padding-top: 0;
  border-top: 1px solid alpha(@unixnotis-outline, 0.30);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.03),
    0 -1px 0 alpha(#06080a, 0.48);
}

.unixnotis-card-grid {
  padding: 0;
}

.unixnotis-info-card {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.12) 0%, alpha(#ffffff, 0.02) 42%, alpha(#000000, 0.08) 100%),
    linear-gradient(155deg, alpha(@unixnotis-surface, 0.98), alpha(@unixnotis-surface-soft, 0.94)),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.07), alpha(#9aa8be, 0.07) 1px, transparent 1px, transparent 14px);
  border-radius: 4px;
  padding: 8px;
  border: 1px solid alpha(@unixnotis-outline, 0.68);
  min-height: 52px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 8px 16px -14px @unixnotis-shadow-soft;
}

.unixnotis-info-card:hover {
  border-color: alpha(@unixnotis-accent-2, 0.58);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.10),
    inset 0 0 0 1px alpha(@unixnotis-accent-2, 0.10),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-info-card:backdrop {
  border-color: alpha(@unixnotis-outline, 0.56);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.66),
    0 8px 14px -14px @unixnotis-shadow-soft;
}

.unixnotis-info-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.unixnotis-info-body {
  font-size: 12px;
  color: @unixnotis-muted;
  line-height: 1.20;
}

.unixnotis-info-card-mono .unixnotis-info-body {
  font-family: "Iosevka Term", "CaskaydiaCove Nerd Font Mono", "JetBrains Mono", monospace;
  color: @unixnotis-text;
  letter-spacing: 0.02em;
}

/* Calendar card */
.unixnotis-calendar {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.10) 0%, alpha(#ffffff, 0.02) 42%, alpha(#000000, 0.08) 100%),
    linear-gradient(160deg, alpha(@unixnotis-card, 0.98), alpha(@unixnotis-surface, 0.96)),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.07), alpha(#9aa8be, 0.07) 1px, transparent 1px, transparent 14px);
  border: 1px solid alpha(@unixnotis-outline, 0.68);
  border-radius: 3px;
  padding: 6px;
  color: @unixnotis-text;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 8px 16px -14px @unixnotis-shadow-soft;
}

.unixnotis-calendar button {
  background-image: linear-gradient(160deg, alpha(@unixnotis-action-bg, 0.9), alpha(@unixnotis-surface-strong, 0.94));
  border-radius: 2px;
  border: 1px solid alpha(@unixnotis-outline, 0.66);
  padding: 2px;
  min-width: 18px;
  min-height: 18px;
  color: @unixnotis-accent;
  -gtk-icon-size: 12px;
  -gtk-icon-style: symbolic;
  -gtk-icon-shadow: 0 0 6px alpha(@unixnotis-accent, 0.45);
  -gtk-icon-palette: success @unixnotis-accent, warning @unixnotis-accent, error @unixnotis-accent;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.08);
}

.unixnotis-calendar button:hover {
  background-image: linear-gradient(160deg, alpha(@unixnotis-action-bg-hover, 0.9), alpha(@unixnotis-accent, 0.22));
  border-color: alpha(@unixnotis-accent, 0.55);
  color: @unixnotis-accent;
}

.unixnotis-calendar button:active {
  background-image: linear-gradient(160deg, alpha(@unixnotis-action-bg-active, 0.85), alpha(@unixnotis-accent, 0.3));
  border-color: alpha(@unixnotis-accent, 0.62);
  color: #ffffff;
}

.unixnotis-calendar button:disabled {
  color: alpha(@unixnotis-muted, 0.6);
  border-color: alpha(@unixnotis-outline, 0.4);
}

.unixnotis-calendar button image,
.unixnotis-calendar button label,
.unixnotis-calendar button arrow,
.unixnotis-calendar button .image,
.unixnotis-calendar button .icon {
  /* Force symbolic icons to render with the same contrast as text. */
  color: inherit;
  -gtk-icon-shadow: 0 0 0 transparent;
  -gtk-icon-palette: success @unixnotis-text, warning @unixnotis-text, error @unixnotis-text;
}

.unixnotis-calendar .header button image,
.unixnotis-calendar .header button label,
.unixnotis-calendar .header button arrow {
  /* Header arrows sometimes inherit muted colors; force the accent to ensure visibility. */
  color: @unixnotis-accent;
  -gtk-icon-shadow: 0 0 6px alpha(@unixnotis-accent, 0.35);
}

.unixnotis-calendar header > button:nth-child(1) {
  /* Prev month */
  -gtk-icon-source: -gtk-icontheme("go-previous-symbolic");
  background-image:
    -gtk-icontheme("go-previous-symbolic"),
    linear-gradient(160deg, alpha(@unixnotis-action-bg, 0.8), alpha(@unixnotis-surface-strong, 0.9));
  background-size: 12px 12px, auto;
  background-repeat: no-repeat, no-repeat;
  background-position: center, center;
}

.unixnotis-calendar header > button:nth-child(3) {
  /* Next month */
  -gtk-icon-source: -gtk-icontheme("go-next-symbolic");
  background-image:
    -gtk-icontheme("go-next-symbolic"),
    linear-gradient(160deg, alpha(@unixnotis-action-bg, 0.8), alpha(@unixnotis-surface-strong, 0.9));
  background-size: 12px 12px, auto;
  background-repeat: no-repeat, no-repeat;
  background-position: center, center;
}

.unixnotis-calendar header > button:nth-child(4) {
  /* Prev year */
  -gtk-icon-source: -gtk-icontheme("go-down-symbolic");
  background-image:
    -gtk-icontheme("go-down-symbolic"),
    linear-gradient(160deg, alpha(@unixnotis-action-bg, 0.8), alpha(@unixnotis-surface-strong, 0.9));
  background-size: 12px 12px, auto;
  background-repeat: no-repeat, no-repeat;
  background-position: center, center;
}

.unixnotis-calendar header > button:nth-child(6) {
  /* Next year */
  -gtk-icon-source: -gtk-icontheme("go-up-symbolic");
  background-image:
    -gtk-icontheme("go-up-symbolic"),
    linear-gradient(160deg, alpha(@unixnotis-action-bg, 0.8), alpha(@unixnotis-surface-strong, 0.9));
  background-size: 12px 12px, auto;
  background-repeat: no-repeat, no-repeat;
  background-position: center, center;
}

.unixnotis-calendar .header {
  color: @unixnotis-muted;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  border-bottom: 1px solid alpha(@unixnotis-outline, 0.42);
  padding-bottom: 6px;
  margin-bottom: 6px;
}

.unixnotis-calendar .day-name {
  color: alpha(@unixnotis-muted, 0.9);
  font-weight: 600;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.unixnotis-calendar .day-number {
  color: @unixnotis-text;
  font-weight: 600;
}

.unixnotis-calendar .day-number.other-month {
  color: alpha(@unixnotis-muted, 0.45);
}

.unixnotis-calendar:selected,
.unixnotis-calendar .day-number:selected {
  background-image: linear-gradient(135deg, alpha(@unixnotis-accent, 0.30), alpha(@unixnotis-accent-2, 0.22));
  color: @unixnotis-text;
  border-radius: 2px;
  box-shadow:
    0 0 0 1px alpha(@unixnotis-accent, 0.52),
    0 0 14px -12px alpha(@unixnotis-accent, 0.52);
}

.unixnotis-calendar .day-number.today {
  box-shadow:
    inset 0 0 0 1px alpha(@unixnotis-accent-2, 0.60),
    0 0 10px -8px alpha(@unixnotis-accent-2, 0.48);
  border-radius: 2px;
}

.unixnotis-info-card-weather {
  background-image:
    radial-gradient(circle at 85% 18%, alpha(@unixnotis-accent, 0.14), transparent 55%),
    linear-gradient(155deg, alpha(@unixnotis-surface-soft, 0.94), alpha(@unixnotis-surface, 0.98));
  border-color: alpha(@unixnotis-accent-2, 0.45);
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-accent-2, 0.10),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-info-card-weather .unixnotis-info-title {
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: @unixnotis-muted;
}

.unixnotis-info-card-weather .unixnotis-info-body {
  font-size: 16px;
  font-weight: 900;
  letter-spacing: 0.03em;
  font-family: "JetBrains Mono", "Iosevka Aile", monospace;
}

.unixnotis-info-icon-weather {
  color: @unixnotis-accent;
}

/*
 * Media carousel
 *
 * Displays active MPRIS players with navigation buttons.
 */
.unixnotis-media-container {
  margin-bottom: 6px;
}

.unixnotis-media-stack {
  background: transparent;
}

.unixnotis-media-row {
  background: transparent;
}

.unixnotis-media-nav {
  background-image: linear-gradient(150deg, @unixnotis-action-bg, alpha(@unixnotis-surface, 0.9));
  border-radius: 3px;
  padding: 2px;
  border: 1px solid alpha(@unixnotis-outline, 0.64);
  font-weight: 700;
  font-size: 10px;
  min-width: 18px;
  color: @unixnotis-text;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.08);
}

.unixnotis-media-nav:hover {
  background-image: linear-gradient(150deg, @unixnotis-action-bg-hover, alpha(@unixnotis-surface-strong, 0.82));
  border-color: alpha(@unixnotis-accent, 0.45);
}

.unixnotis-media-position {
  color: @unixnotis-muted;
  font-size: 10px;
  letter-spacing: 0.08em;
}

.unixnotis-media-card {
  background-image:
    linear-gradient(180deg, alpha(#ffffff, 0.11) 0%, alpha(#ffffff, 0.02) 40%, alpha(#000000, 0.08) 100%),
    linear-gradient(155deg, @unixnotis-notification-bg-1 0%, @unixnotis-notification-bg-2 100%),
    repeating-linear-gradient(0deg, alpha(#9aa8be, 0.07), alpha(#9aa8be, 0.07) 1px, transparent 1px, transparent 14px);
  border-radius: 4px;
  border: 1px solid @unixnotis-card-border;
  padding: 6px 8px;
  min-height: 56px;
  box-shadow:
    inset 0 1px 0 alpha(#ffffff, 0.08),
    inset 0 0 0 1px alpha(@unixnotis-outline, 0.10),
    0 10px 18px -14px @unixnotis-shadow-soft;
}

.unixnotis-media-card.playing {
  border-left: 2px solid alpha(@unixnotis-accent, 0.7);
}

.unixnotis-media-art {
  min-width: 40px;
  min-height: 40px;
  border-radius: 2px;
  background: alpha(@unixnotis-surface-strong, 0.72);
}

.unixnotis-media-art-frame {
  min-width: 44px;
  min-height: 44px;
  border-radius: 2px;
  background: alpha(@unixnotis-surface-strong, 0.80);
  border: 1px solid alpha(@unixnotis-outline, 0.62);
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.08);
}

.unixnotis-media-art.empty {
  background: alpha(@unixnotis-surface-strong, 0.60);
}

.unixnotis-media-source {
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: @unixnotis-muted;
}

.unixnotis-media-title {
  font-weight: 700;
  font-size: 11px;
}

.unixnotis-marquee {
  background: transparent;
  padding: 0;
  margin: 0;
}

.unixnotis-media-artist {
  color: @unixnotis-muted;
  font-size: 10px;
}

.unixnotis-media-artist.empty {
  color: transparent;
}

.unixnotis-media-controls {
  background: transparent;
}

.unixnotis-media-button {
  background-image: linear-gradient(160deg, @unixnotis-action-bg, alpha(@unixnotis-surface, 0.95));
  border-radius: 3px;
  border: 1px solid alpha(@unixnotis-outline, 0.64);
  padding: 3px 5px;
  box-shadow: inset 0 1px 0 alpha(#ffffff, 0.08);
}

.unixnotis-media-button:hover {
  background-image: linear-gradient(160deg, @unixnotis-action-bg-hover, alpha(@unixnotis-surface-strong, 0.84));
  border-color: alpha(@unixnotis-accent, 0.46);
}

.unixnotis-media-button.primary {
  background-image: linear-gradient(160deg, @unixnotis-action-bg-active, alpha(@unixnotis-accent-2, 0.22));
  border-color: alpha(@unixnotis-accent, 0.62);
  color: #ffffff;
}
installer.toml
# UnixNotis installer settings
# Backup retention for config/theme resets.
[backups]
keep = 3
scripts/unixnotis-creative-status
#!/usr/bin/env bash
set -euo pipefail

# Emit a compact system pulse card for UnixNotis widget plugin API v1
# Command selection stays lightweight to keep refresh cost low

now_hm="$(date '+%H:%M')"

read -r uptime_seconds _ < /proc/uptime
uptime_minutes=$(( ${uptime_seconds%.*} / 60 ))
uptime_hours=$(( uptime_minutes / 60 ))
uptime_remainder_minutes=$(( uptime_minutes % 60 ))

if (( uptime_hours > 0 )); then
  uptime_human="${uptime_hours}h ${uptime_remainder_minutes}m"
else
  uptime_human="${uptime_remainder_minutes}m"
fi

read -r load_1 load_5 load_15 _ < /proc/loadavg

battery_line="AC power"
for battery_dir in /sys/class/power_supply/BAT*; do
  if [[ -d "$battery_dir" ]]; then
    capacity="$(cat "$battery_dir/capacity" 2>/dev/null || echo "?")"
    status="$(cat "$battery_dir/status" 2>/dev/null || echo "Unknown")"
    battery_line="${capacity}% (${status})"
    break
  fi
done

title="Kernel Pulse"
text="$(printf 'time : %s\nup   : %s\nload : %s %s %s\nbatt : %s' "$now_hm" "$uptime_human" "$load_1" "$load_5" "$load_15" "$battery_line")"

jq -nc --arg title "$title" --arg text "$text" '{api_version:1,title:$title,text:$text}'
scripts/unixnotis-net-rate-stat
#!/usr/bin/env bash
set -euo pipefail

# Emit aggregate network throughput as a stat payload for widget plugin API v1.
# State is persisted under the runtime directory to derive a short-interval rate.

state_dir="${XDG_RUNTIME_DIR:-/tmp}/unixnotis"
state_file="${state_dir}/net-rate.state"
mkdir -p "$state_dir"

now_ns="$(date +%s%N)"
read -r rx_now tx_now <<DATA
$(awk -F '[: ]+' 'BEGIN { rx=0; tx=0 } $1 !~ /^lo$/ && $1 != "" { rx += $3; tx += $11 } END { print rx, tx }' /proc/net/dev)
DATA

format_rate() {
  local bytes_per_sec="$1"
  if (( bytes_per_sec >= 1048576 )); then
    printf '%.1fM' "$(awk -v b="$bytes_per_sec" 'BEGIN { print b / 1048576.0 }')"
  elif (( bytes_per_sec >= 1024 )); then
    printf '%.0fK' "$(awk -v b="$bytes_per_sec" 'BEGIN { print b / 1024.0 }')"
  else
    printf '%dB' "$bytes_per_sec"
  fi
}

if [[ -f "$state_file" ]]; then
  read -r prev_ns prev_rx prev_tx < "$state_file" || true
else
  prev_ns=0
  prev_rx="$rx_now"
  prev_tx="$tx_now"
fi

rate_rx=0
rate_tx=0
if [[ "$prev_ns" =~ ^[0-9]+$ ]] && (( prev_ns > 0 )) && (( now_ns > prev_ns )); then
  dt_ns=$(( now_ns - prev_ns ))
  drx=$(( rx_now - prev_rx ))
  dtx=$(( tx_now - prev_tx ))
  if (( drx < 0 )); then drx=0; fi
  if (( dtx < 0 )); then dtx=0; fi
  rate_rx=$(( drx * 1000000000 / dt_ns ))
  rate_tx=$(( dtx * 1000000000 / dt_ns ))
fi

printf '%s %s %s\n' "$now_ns" "$rx_now" "$tx_now" > "$state_file"

text="$(printf 'D:%s U:%s' "$(format_rate "$rate_rx")" "$(format_rate "$rate_tx")")"
jq -nc --arg text "$text" '{api_version:1,text:$text}'
scripts/unixnotis-process-card
#!/usr/bin/env bash
set -euo pipefail

# Emit process pressure snapshot as a compact card payload for widget plugin API v1

read_proc_line() {
  ps -eo comm=,%cpu=,%mem= --sort=-%cpu | awk 'NR==1 { print $1, $2, $3 }'
}

proc_line="$(read_proc_line 2>/dev/null || true)"

if [[ -z "$proc_line" ]]; then
  text="cpu : n/a\nmem : n/a"
else
  proc_cpu="$(awk '{print $2}' <<< "$proc_line")"
  proc_mem="$(awk '{print $3}' <<< "$proc_line")"
  if [[ -z "$proc_cpu" ]]; then proc_cpu="0.0"; fi
  if [[ -z "$proc_mem" ]]; then proc_mem="0.0"; fi
  text="$(printf 'cpu : %s%%\nmem : %s%%' "$proc_cpu" "$proc_mem")"
fi

jq -nc --arg title "Hot Process" --arg text "$text" '{api_version:1,title:$title,text:$text}'
scripts/unixnotis-storage-card
#!/usr/bin/env bash
set -euo pipefail

# Emit storage summary as a compact card payload for widget plugin API v1

read_root_line() {
  df -h --output=target,size,used,avail,pcent / | awk 'NR==2 { print $0 }'
}

read_home_line() {
  df -h --output=target,size,used,avail,pcent "$HOME" | awk 'NR==2 { print $0 }'
}

root_line="$(read_root_line 2>/dev/null || true)"
home_line="$(read_home_line 2>/dev/null || true)"

if [[ -z "$root_line" ]]; then
  text="storage: n/a"
else
  root_size="$(awk '{print $2}' <<< "$root_line")"
  root_used="$(awk '{print $3}' <<< "$root_line")"
  root_avail="$(awk '{print $4}' <<< "$root_line")"
  root_pct="$(awk '{print $5}' <<< "$root_line")"
  printf -v text '/ used %s of %s | free %s\nutil: %s' "$root_used" "$root_size" "$root_avail" "$root_pct"

  if [[ -n "$home_line" ]]; then
    home_used="$(awk '{print $3}' <<< "$home_line")"
    home_size="$(awk '{print $2}' <<< "$home_line")"
    home_pct="$(awk '{print $5}' <<< "$home_line")"
    printf -v text '%s\nhome: %s/%s (%s)' "$text" "$home_used" "$home_size" "$home_pct"
  fi
fi

jq -nc --arg title "Storage Map" --arg text "$text" '{api_version:1,title:$title,text:$text}'
scripts/unixnotis-thermal-stat
#!/usr/bin/env bash
set -euo pipefail

# Emit CPU/package thermal data as a stat payload for widget plugin API v1.

best_temp_milli=""
best_label=""

for zone in /sys/class/thermal/thermal_zone*; do
  [[ -d "$zone" ]] || continue
  temp_file="$zone/temp"
  type_file="$zone/type"
  [[ -r "$temp_file" ]] || continue

  temp_raw="$(cat "$temp_file" 2>/dev/null || true)"
  [[ "$temp_raw" =~ ^[0-9]+$ ]] || continue
  (( temp_raw > 0 )) || continue

  zone_type="$(cat "$type_file" 2>/dev/null || echo "thermal")"
  zone_type="${zone_type,,}"

  # Prefer package/cpu zones where available, otherwise keep the hottest reading.
  if [[ "$zone_type" == *"pkg"* || "$zone_type" == *"cpu"* ]]; then
    best_temp_milli="$temp_raw"
    best_label="cpu"
    break
  fi

  if [[ -z "$best_temp_milli" ]] || (( temp_raw > best_temp_milli )); then
    best_temp_milli="$temp_raw"
    best_label="sys"
  fi
done

if [[ -z "$best_temp_milli" ]]; then
  text="n/a"
else
  temp_c="$(awk -v t="$best_temp_milli" 'BEGIN { printf "%.1f", t / 1000.0 }')"
  text="${best_label}:${temp_c}C"
fi

jq -nc --arg text "$text" '{api_version:1,text:$text}'
scripts/unixnotis-toolchain-card
#!/usr/bin/env bash
set -euo pipefail

# Emit compiler/toolchain snapshot as compact text for a card widget

first_num() {
  grep -Eo '[0-9]+([.][0-9]+)+' | head -n 1
}

get_ver() {
  local bin="$1"
  local line=""
  local ver=""
  if ! command -v "$bin" >/dev/null 2>&1; then
    printf 'n/a'
    return
  fi

  case "$bin" in
    ld) line="$(ld -v 2>/dev/null | head -n 1 || true)" ;;
    *) line="$($bin --version 2>/dev/null | head -n 1 || true)" ;;
  esac

  if [[ -z "$line" ]]; then
    printf 'n/a'
    return
  fi

  ver="$(printf '%s\n' "$line" | first_num)"
  if [[ -z "$ver" ]]; then
    printf 'ok'
  else
    printf '%s' "$ver"
  fi
}

kernel_raw="$(uname -r 2>/dev/null || echo n/a)"
machine="$(uname -m 2>/dev/null || echo n/a)"
gcc_v="$(get_ver gcc)"
clang_v="$(get_ver clang)"
rust_v="$(get_ver rustc)"
nasm_v="$(get_ver nasm)"
ld_v="$(get_ver ld)"

# Keep only major.minor kernel version so the card stays informative
# without printing full distro/build identifiers
kernel_short="$(printf '%s\n' "$kernel_raw" | grep -Eo '^[0-9]+([.][0-9]+){0,2}' | cut -d. -f1-2)"
if [[ -z "$kernel_short" ]]; then
  kernel_short="n/a"
fi

printf 'kernel: %s | %s\n' "$kernel_short" "$machine"
printf 'gcc/clang: %s / %s\n' "$gcc_v" "$clang_v"
printf 'rust/nasm: %s / %s\n' "$rust_v" "$nasm_v"
printf 'binutils : %s\n' "$ld_v"

Clone this wiki locally