diff --git a/.config/waybar/base.jsonc##hostname.viking-mate b/.config/waybar/base.jsonc##hostname.viking-mate
new file mode 100644
index 0000000..173954b
--- /dev/null
+++ b/.config/waybar/base.jsonc##hostname.viking-mate
@@ -0,0 +1,207 @@
+{
+ // Shared defaults & core module definitions (laptop host)
+ "layer": "bottom",
+ "position": "bottom",
+ "mod": "dock",
+ "exclusive": true,
+ "gtk-layer-shell": true,
+ "passthrough": false,
+ "fixed-center": true,
+ "height": 32,
+ "spacing": 8,
+
+ // Hyprland
+ "hyprland/workspaces": {
+ "icon-size": 24,
+ "spacing": 10,
+ "all-outputs": true,
+ "on-scroll-up": "hyprctl dispatch workspace r+1",
+ "on-scroll-down": "hyprctl dispatch workspace r-1"
+ },
+ "hyprland/window": {
+ "format": "{title}",
+ "max-length": 56,
+ "separate-outputs": false,
+ "tooltip": true
+ },
+
+ // System stats
+ "cpu": { "interval": 5, "format": " {usage}%", "tooltip": true, "on-click": "alacritty -e btop" },
+ "memory": { "interval": 11, "format": " {percentage}%", "tooltip": true, "on-click": "alacritty -e btop" },
+ "custom/temps": {
+ "exec-if": "command -v sensors >/dev/null",
+ "exec": "bash -lc \"sensors | awk '/Tctl|Tdie|Package id 0/{gsub(/\\+|°C/,\\\"\\\"); print int($2); exit}'\"",
+ "interval": 5,
+ "format": " {output}°C",
+ "tooltip": true,
+ "on-click": "alacritty -e watch -n 1 sensors"
+ },
+
+ // Disks (keep minimal on laptop)
+ "disk#root": {
+ "interval": 29,
+ "path": "/",
+ "format": " {percentage_used}%",
+ "tooltip": true,
+ "tooltip-format": "Root: {used} / {total} ({percentage_used}%)"
+ },
+
+ // Media
+ "mpris": {
+ "format": "{player_icon} {dynamic}",
+ "format-paused": "{status_icon} {dynamic}",
+ "dynamic-len": 40,
+ "ellipsis": "…",
+ "player-icons": { "default": "▶", "mpv": "🎵", "spotify": "" },
+ "status-icons": { "paused": "⏸" },
+ "on-click": "playerctl play-pause",
+ "on-click-right": "playerctl next",
+ "on-click-middle": "playerctl previous",
+ "on-scroll-up": "playerctl position 5+",
+ "on-scroll-down": "playerctl position 5-",
+ "tooltip": true
+ },
+
+ // Network / Audio / BT
+ "network": {
+ "format-wifi": " {essid} ({signalStrength}%)",
+ "format-ethernet": " {ifname}",
+ "format-disconnected": " Disconnected",
+ "tooltip": true,
+ "tooltip-format": "{ifname} → {gwaddr}",
+ "on-click": "nm-connection-editor",
+ "on-click-right": "alacritty -e nmtui"
+ },
+ "pulseaudio": {
+ "format": "{icon} {volume}%",
+ "format-muted": " Muted",
+ "scroll-step": 5,
+ "interval": 30,
+ "tooltip": true,
+ "on-click": "pavucontrol",
+ "on-click-right": "pactl set-sink-mute @DEFAULT_SINK@ toggle",
+ "format-icons": { "default": ["", ""] }
+ },
+ "bluetooth": {
+ "format": " {status}",
+ "format-connected": " {device_alias} ({device_battery_percentage}%)",
+ "tooltip": true,
+ "on-click": "blueman-manager"
+ },
+
+ // Backlight (screen)
+ "backlight": {
+ "interval": 2,
+ "format": " {percent}%",
+ "on-scroll-up": "brightnessctl set +5%",
+ "on-scroll-down": "brightnessctl set 5%-",
+ "tooltip": true
+ },
+
+ // Power
+ "battery": {
+ "states": { "good": 95, "warning": 30, "critical": 20 },
+ "format": "{icon} {capacity}%",
+ "format-alt": "{icon} {capacity}% ({time})",
+ "format-charging": " {capacity}%",
+ "format-full": " {capacity}%",
+ "tooltip": true,
+ "interval": 15,
+ "format-icons": ["","","","",""]
+ },
+ "power-profiles-daemon": {
+ "format": " {profile}",
+ "tooltip": true,
+ "on-click": "bash -lc 'cur=$(powerprofilesctl get); case $cur in performance) nxt=balanced;; balanced) nxt=powersave;; *) nxt=performance;; esac; powerprofilesctl set $nxt; notify-send -a waybar \"Power Profile\" \"Switched to $nxt\"'"
+ },
+
+ // Hyprsunset (reusing your existing script wiring & daemon)
+ "custom/hyprsunset": {
+ "exec-if": "[ -x $HOME/.config/waybar/scripts/hyprsunset_toggle.sh ]",
+ "exec": "$HOME/.config/waybar/scripts/hyprsunset_toggle.sh --print",
+ "return-type": "json",
+ "interval": 60,
+ "signal": 5,
+ "format": "{text}",
+ "tooltip": true,
+ "on-click": "bash -lc '$HOME/.config/waybar/scripts/hyprsunset_toggle.sh --toggle-auto && pkill -SIGRTMIN+5 waybar'",
+ "on-click-right": "bash -lc '$HOME/.config/waybar/scripts/hyprsunset_toggle.sh --toggle && pkill -SIGRTMIN+5 waybar'",
+ "on-scroll-up": "bash -lc 't=$($HOME/.config/waybar/scripts/hyprsunset_toggle.sh --print | sed -n \"s/.* \\([0-9]\\+\\)K.*/\\1/p\"); [ -z \"$t\" ] && t=3800; t=$((t+200)); $HOME/.config/waybar/scripts/hyprsunset_toggle.sh --set $t && pkill -SIGRTMIN+5 waybar'",
+ "on-scroll-down": "bash -lc 't=$($HOME/.config/waybar/scripts/hyprsunset_toggle.sh --print | sed -n \"s/.* \\([0-9]\\+\\)K.*/\\1/p\"); [ -z \"$t\" ] && t=3800; t=$((t-200)); [ $t -lt 1000 ] && t=1000; $HOME/.config/waybar/scripts/hyprsunset_toggle.sh --set $t && pkill -SIGRTMIN+5 waybar'"
+ },
+
+ // Extra laptop customs (defined by scripts below)
+ "custom/wifi": {
+ "exec-if": "command -v nmcli >/dev/null",
+ "exec": "$HOME/.config/waybar/scripts/wifi_toggle.sh --print",
+ "return-type": "json",
+ "interval": 5,
+ "signal": 10,
+ "format": "{text}",
+ "tooltip": true,
+ "on-click": "bash -lc '$HOME/.config/waybar/scripts/wifi_toggle.sh --toggle && pkill -SIGRTMIN+10 waybar'"
+ },
+ "custom/bt": {
+ "exec-if": "command -v bluetoothctl >/dev/null",
+ "exec": "$HOME/.config/waybar/scripts/bt_toggle.sh --print",
+ "return-type": "json",
+ "interval": 5,
+ "signal": 11,
+ "format": "{text}",
+ "tooltip": true,
+ "on-click": "bash -lc '$HOME/.config/waybar/scripts/bt_toggle.sh --toggle && pkill -SIGRTMIN+11 waybar'"
+ },
+ "custom/airplane": {
+ "exec-if": "command -v rfkill >/dev/null",
+ "exec": "$HOME/.config/waybar/scripts/airplane_mode.sh --print",
+ "return-type": "json",
+ "interval": 7,
+ "signal": 12,
+ "format": "{text}",
+ "tooltip": true,
+ "on-click": "bash -lc '$HOME/.config/waybar/scripts/airplane_mode.sh --toggle && pkill -SIGRTMIN+12 waybar'"
+ },
+ "custom/kbdlight": {
+ "exec-if": "command -v brightnessctl >/dev/null",
+ "exec": "$HOME/.config/waybar/scripts/kbdlight.sh --print",
+ "return-type": "json",
+ "interval": 4,
+ "signal": 13,
+ "format": "{text}",
+ "tooltip": true,
+ "on-scroll-up": "bash -lc '$HOME/.config/waybar/scripts/kbdlight.sh --inc && pkill -SIGRTMIN+13 waybar'",
+ "on-scroll-down": "bash -lc '$HOME/.config/waybar/scripts/kbdlight.sh --dec && pkill -SIGRTMIN+13 waybar'"
+ },
+ "custom/batteryhealth": {
+ "exec-if": "command -v upower >/dev/null",
+ "exec": "$HOME/.config/waybar/scripts/battery_health.sh",
+ "return-type": "json",
+ "interval": 120,
+ "signal": 14,
+ "format": "{text}",
+ "tooltip": true
+ },
+
+ // Performance (same concept as desktop)
+ "custom/performance": {
+ "exec-if": "[ -x $HOME/.config/waybar/scripts/performance.sh ]",
+ "exec": "$HOME/.config/waybar/scripts/performance.sh",
+ "interval": 10,
+ "signal": 6,
+ "tooltip": true,
+ "on-click": "bash -lc '$HOME/.config/waybar/scripts/performance.sh toggle >/dev/null 2>&1; pkill -SIGRTMIN+6 waybar'",
+ "on-click-right": "bash -lc '$HOME/.config/waybar/scripts/performance.sh cycle >/dev/null 2>&1; pkill -SIGRTMIN+6 waybar'",
+ "format": "{text}"
+ },
+
+ // Tray / Clock / Privacy
+ "tray": { "icon-size": 18, "spacing": 4 },
+ "clock": {
+ "format": "{:%R | %d.%m.%Y}",
+ "tooltip-format": "{calendar}",
+ "calendar": { "mode": "year", "mode-mon-col": 3, "weeks-pos": "right" },
+ "actions": { "on-click-right": "mode", "on-scroll-up": "shift_up", "on-scroll-down": "shift_down" }
+ },
+ "privacy": { "icon-size": 16, "tooltip": true }
+}
+
diff --git a/.config/waybar/conf.d/laptop.jsonc##hostname.viking-mate b/.config/waybar/conf.d/laptop.jsonc##hostname.viking-mate
new file mode 100644
index 0000000..4a5d30e
--- /dev/null
+++ b/.config/waybar/conf.d/laptop.jsonc##hostname.viking-mate
@@ -0,0 +1,41 @@
+{
+ "name": "bar-laptop",
+ "output": "eDP-1", // change if your panel isn't eDP-1
+ "height": 32,
+ "spacing": 8,
+
+ "modules-left": ["hyprland/workspaces", "hyprland/window"],
+ "modules-center": ["privacy", "mpris"],
+ "modules-right": [
+ "group/sys",
+ "network",
+ "backlight",
+ "custom/kbdlight",
+ "pulseaudio",
+ "bluetooth",
+ "custom/wifi",
+ "custom/bt",
+ "custom/airplane",
+ "battery",
+ "custom/batteryhealth",
+ "power-profiles-daemon",
+ "custom/performance",
+ "custom/hyprsunset",
+ "tray",
+ "clock"
+ ],
+
+ // Drawer for noisy stats to save width
+ "custom/sys": { "format": "", "tooltip": true },
+ "group/sys": {
+ "orientation": "horizontal",
+ "drawer": {
+ "transition-duration": 300,
+ "children-class": "sys",
+ "click-to-reveal": true,
+ "transition-left-to-right": false
+ },
+ "modules": ["custom/sys", "cpu", "memory", "custom/temps", "disk#root"]
+ }
+}
+
diff --git a/.config/waybar/config.jsonc##hostname.viking-mate b/.config/waybar/config.jsonc##hostname.viking-mate
new file mode 100644
index 0000000..ced45b9
--- /dev/null
+++ b/.config/waybar/config.jsonc##hostname.viking-mate
@@ -0,0 +1,4 @@
+[
+ { "include": ["base.jsonc", "conf.d/laptop.jsonc"] }
+]
+
diff --git a/.config/waybar/scripts/airplane_mode.sh b/.config/waybar/scripts/airplane_mode.sh
new file mode 100755
index 0000000..13d5677
--- /dev/null
+++ b/.config/waybar/scripts/airplane_mode.sh
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+set -euo pipefail
+is_blocked_all() { rfkill list | awk '/Soft blocked:/{c++;/yes/&&y++} END{exit !(c>0 && c==y)}'; }
+print() {
+ if is_blocked_all; then
+ echo '{"text":"✈","class":"on","tooltip":"Airplane mode: ON (click to disable)"}'
+ else
+ echo '{"text":"✈","class":"off","tooltip":"Airplane mode: OFF (click to enable)"}'
+ fi
+}
+case "${1:---print}" in
+ --toggle)
+ if is_blocked_all; then rfkill unblock all; else rfkill block all; fi
+ ;;
+ --print) : ;;
+ *) echo "Usage: $0 [--toggle|--print]"; exit 1 ;;
+esac
+print
+
diff --git a/.config/waybar/scripts/battery_health.sh b/.config/waybar/scripts/battery_health.sh
new file mode 100755
index 0000000..c0a9bc1
--- /dev/null
+++ b/.config/waybar/scripts/battery_health.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+set -euo pipefail
+bat="$(upower -e | grep -m1 BAT || true)"
+if [ -z "$bat" ]; then
+ echo '{"text":" --","class":"no-battery","tooltip":"No battery found"}'
+ exit 0
+fi
+info="$(upower -i "$bat")"
+full=$(echo "$info" | awk -F: '/energy-full:/{gsub(/[^0-9.]/,"",$2); print $2; exit}')
+design=$(echo "$info" | awk -F: '/energy-full-design:/{gsub(/[^0-9.]/,"",$2); print $2; exit}')
+if [ -z "$full" ] || [ -z "$design" ] || [ "$design" = "0" ]; then
+ # Try charge-full fallback
+ full=$(echo "$info" | awk -F: '/charge-full:/{gsub(/[^0-9.]/,"",$2); print $2; exit}')
+ design=$(echo "$info" | awk -F: '/charge-full-design:/{gsub(/[^0-9.]/,"",$2); print $2; exit}')
+fi
+wear="--"
+if [ -n "$full" ] && [ -n "$design" ] && [ "$design" != "0" ]; then
+ health=$(awk -v f="$full" -v d="$design" 'BEGIN{printf "%.0f", (f/d)*100}')
+ wear=$(( 100 - health ))
+ text="❤ ${health}%"
+else
+ text="❤ --"
+fi
+cycles=$(echo "$info" | awk -F: '/cycle count:/{gsub(/[^0-9]/,"",$2); print $2; exit}')
+vendor=$(echo "$info" | awk -F: '/vendor:/{gsub(/^ +/,"",$2); print $2; exit}')
+model=$(echo "$info" | awk -F: '/model:/{gsub(/^ +/,"",$2); print $2; exit}')
+tt="Battery health info\nWear: ${wear}%\nCycles: ${cycles:---}\nVendor: ${vendor:---}\nModel: ${model:---}"
+printf '{"text":"%s","class":"battery-health","tooltip":"%s"}\n' "$text" "$(echo "$tt" | sed ':a;N;$!ba;s/\n/\\n/g')"
+
diff --git a/.config/waybar/scripts/bt_toggle.sh b/.config/waybar/scripts/bt_toggle.sh
new file mode 100755
index 0000000..97a8608
--- /dev/null
+++ b/.config/waybar/scripts/bt_toggle.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+set -euo pipefail
+status() { bluetoothctl show 2>/dev/null | awk '/Powered:/ {print tolower($2); exit}'; } # yes/no
+print() {
+ s="$(status)"; s="${s:-no}"
+ if [ "$s" = "yes" ]; then
+ echo '{"text":"","class":"on","tooltip":"Bluetooth: on (click to toggle)"}'
+ else
+ echo '{"text":"","class":"off","tooltip":"Bluetooth: off (click to toggle)"}'
+ fi
+}
+case "${1:---print}" in
+ --toggle) [ "$(status)" = "yes" ] && bluetoothctl power off || bluetoothctl power on ;;
+ --print) : ;;
+ *) echo "Usage: $0 [--toggle|--print]"; exit 1 ;;
+esac
+print
+
diff --git a/.config/waybar/scripts/kbdlight.sh b/.config/waybar/scripts/kbdlight.sh
new file mode 100755
index 0000000..85c6763
--- /dev/null
+++ b/.config/waybar/scripts/kbdlight.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+set -euo pipefail
+dev() { brightnessctl --list 2>/dev/null | awk '/kbd_backlight/ {print $2; exit}'; }
+get_vals() {
+ d="$(dev)"; [ -z "$d" ] && return 1
+ cur="$(brightnessctl -d "$d" get)"; max="$(brightnessctl -d "$d" max)"
+ echo "$d;$cur;$max"
+}
+print() {
+ if vals="$(get_vals)"; then
+ IFS=';' read -r d cur max <<<"$vals"
+ [ "$max" -gt 0 ] || max=1
+ pct=$(( cur * 100 / max ))
+ # show in steps if small range
+ steps=$(( max>10 ? 10 : max ))
+ step=$(( cur * steps / max ))
+ echo "{\"text\":\"⌨ ${pct}%\",\"class\":\"kbd $step/$steps\",\"tooltip\":\"Keyboard backlight: ${cur}/${max} (${pct}%)\\nScroll to adjust\"}"
+ else
+ echo '{"text":"⌨","class":"kbd none","tooltip":"No keyboard backlight device found"}'
+ fi
+}
+case "${1:---print}" in
+ --inc) if vals="$(get_vals)"; then IFS=';' read -r d cur max <<<"$vals"; brightnessctl -d "$d" set +1 >/dev/null; fi ;;
+ --dec) if vals="$(get_vals)"; then IFS=';' read -r d cur max <<<"$vals"; brightnessctl -d "$d" set 1- >/dev/null; fi ;;
+ --print) : ;;
+ *) echo "Usage: $0 [--inc|--dec|--print]"; exit 1 ;;
+esac
+print
+
diff --git a/.config/waybar/scripts/wifi_toggle.sh b/.config/waybar/scripts/wifi_toggle.sh
new file mode 100755
index 0000000..8e69c85
--- /dev/null
+++ b/.config/waybar/scripts/wifi_toggle.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+set -euo pipefail
+status() { nmcli -t -f WIFI g | awk -F: '{print $1}'; } # enabled/disabled
+print() {
+ s="$(status)"
+ if [ "$s" = "enabled" ]; then
+ echo '{"text":"","class":"on","tooltip":"Wi-Fi: enabled (click to toggle)"}'
+ else
+ echo '{"text":"","class":"off","tooltip":"Wi-Fi: disabled (click to toggle)"}'
+ fi
+}
+case "${1:---print}" in
+ --toggle) [ "$(status)" = "enabled" ] && nmcli radio wifi off || nmcli radio wifi on ;;
+ --print) : ;;
+ *) echo "Usage: $0 [--toggle|--print]"; exit 1 ;;
+esac
+print
+
diff --git a/.config/waybar/style.css b/.config/waybar/style.css
new file mode 120000
index 0000000..46e9c4a
--- /dev/null
+++ b/.config/waybar/style.css
@@ -0,0 +1 @@
+style.css##hostname.cn-arch
\ No newline at end of file
diff --git a/.config/waybar/style.css##hostname.cn-arch b/.config/waybar/style.css##hostname.cn-arch
deleted file mode 100644
index a2e161e..0000000
--- a/.config/waybar/style.css##hostname.cn-arch
+++ /dev/null
@@ -1,181 +0,0 @@
-/* =========================
- Midnight-Ocean — Waybar GTK CSS
- ========================= */
-
-/* Palette */
-@define-color bg_main rgba(11, 27, 43, 0.85);
-@define-color bg_main_tooltip rgba(11, 27, 43, 0.95);
-@define-color bg_hover rgba(79, 132, 204, 0.3);
-@define-color bg_active rgba(53, 107, 171, 0.7);
-@define-color border_main rgba(79, 132, 204, 0.5);
-@define-color content_main #FFFFFF; /* ← all text white */
-@define-color content_inactive rgba(255, 255, 255, 0.45);
-@define-color warning_color #FFCC33;
-
-/* Reset & Font */
-* {
- font-family: "Inconsolata Go Nerd Font";
- font-size: 14px;
- text-shadow: none;
- box-shadow: none;
- border-radius: 0;
- margin: 0;
- padding: 0;
- color: @content_main;
-}
-
-/* Bar Background */
-window#waybar {
- background: @bg_main;
- border-top: 1px solid @border_main;
-}
-
-/* Per-bar sizing nudges */
-window#waybar.bar-dp2 * {
- font-size: 14px;
-}
-window#waybar.bar-dp1 * {
- font-size: 14px;
-}
-window#waybar.bar-hdmi * {
- font-size: 13px;
-}
-
-/* Tooltips */
-tooltip {
- background: @bg_main_tooltip;
- border: 1px solid @border_main;
- border-radius: 4px;
- padding: 4px 6px;
-}
-
-/* Module Spacing & Hover */
-.module {
- padding: 0 6px;
- margin: 0 2px;
-}
-.module:hover {
- background: @bg_hover;
-}
-
-/* HDMI: tighter modules to free center space */
-window#waybar.bar-hdmi .module {
- padding: 0 4px;
-}
-
-/* Collapse empty/noise modules */
-#mpris.empty,
-#bluetooth.disconnected {
- padding: 0;
- margin: 0;
- border: none;
-}
-
-/* Separators */
-#cpu,
-#memory,
-#disk,
-#disk-nvme0,
-#disk-nvme1,
-#network,
-#pulseaudio,
-#bluetooth,
-#power-profiles-daemon,
-#custom-alhp,
-#custom-razer-mouse-battery,
-#custom-hyprsunset {
- /* ← new module gets a separator too */
- border-right: 1px solid @border_main;
-}
-
-/* Workspaces */
-#workspaces {
- margin: 0 2px;
-}
-#workspaces button {
- padding: 4px 6px;
- color: @content_inactive;
-}
-#workspaces button:hover {
- background: @bg_hover;
- color: @content_main;
-}
-#workspaces button.active {
- background: @bg_active;
- color: @content_main;
- font-weight: 600;
-}
-#workspaces button.urgent {
- background: rgba(255, 204, 51, 0.35);
- color: @warning_color;
-}
-
-/* Window title (hyprland/window): truncation via config max-length */
-#window {
- min-width: 0;
- font-weight: 500;
- padding: 0 6px;
-}
-
-/* MPRIS */
-#mpris {
- min-width: 0;
- padding: 0 6px;
-}
-
-/* Tray & Clock */
-#tray,
-#clock {
- padding: 0 6px;
-}
-#tray > .passive {
- opacity: 0.7;
-}
-#tray > .needs-attention {
- color: @warning_color;
-}
-
-/* Battery states */
-#battery.warning {
- color: @warning_color;
-}
-#battery.critical {
- color: @warning_color;
-}
-#battery.critical span {
- color: @warning_color;
-}
-
-/* Optional subtle accent for quick scanning (kept minimal; text still white overall) */
-#cpu,
-#network,
-#pulseaudio,
-#bluetooth,
-#mpris,
-#custom-hyprsunset {
- color: #dee6f7; /* very light tint; still reads as white on dark */
-}
-
-/* Drawer polish (DP-1) */
-#custom-sys {
- padding: 0 8px;
- font-weight: 600;
-}
-.sys {
- padding: 0 6px;
-}
-.revealed .sys {
- background: rgba(79, 132, 204, 0.12);
-}
-
-/* Customs */
-#custom-alhp,
-#custom-razer-mouse-battery,
-#custom-hyprsunset {
- padding: 0 6px;
-}
-
-/* Network states */
-#network.disconnected {
- color: @warning_color;
-}