diff --git a/themes/executive-ivory.json b/themes/executive-ivory.json new file mode 100644 index 0000000..6536493 --- /dev/null +++ b/themes/executive-ivory.json @@ -0,0 +1,60 @@ +{ + "version": 1, + "name": "Executive Ivory", + "slug": "executive-ivory", + "mode": "light", + "wallpaper": "", + "colors": { + "base": "#F2F0E9", + "mantle": "#DCD9CE", + "surface": "#E8E5DB", + "overlay": "#ABA898", + "text": "#252D3B", + "subtext": "#4A5568", + "muted": "#767E8D", + "accent": "#2F5FBF", + "accentAlt": "#46689E", + "good": "#3E7449", + "warn": "#8D6110", + "bad": "#A84048" + }, + "border": { + "active": "accent", + "inactive": "overlay" + }, + "fonts": { + "mono": "JetBrainsMono Nerd Font", + "ui": "Inter", + "size": 11 + }, + "ui": { + "gapsIn": 5, + "gapsOut": 12, + "borderSize": 2, + "rounding": 10, + "iconSize": 36, + "activeOpacity": 1.0, + "inactiveOpacity": 0.95, + "terminalOpacity": 0.96, + "blur": true, + "shadow": true + }, + "ansi": [ + "#252D3B", + "#A84048", + "#3E7449", + "#8D6110", + "#2F5FBF", + "#6B4FA8", + "#2E7D88", + "#F2F0E9", + "#767E8D", + "#BC5560", + "#4F8A5B", + "#A5761A", + "#4674D0", + "#7E63BE", + "#3D93A0", + "#FAF9F4" + ] +} diff --git a/themes/executive-ivory/btop.theme b/themes/executive-ivory/btop.theme new file mode 100644 index 0000000..a4b3ed9 --- /dev/null +++ b/themes/executive-ivory/btop.theme @@ -0,0 +1,25 @@ +theme[main_bg]="#F2F0E9" +theme[main_fg]="#252D3B" +theme[title]="#252D3B" +theme[hi_fg]="#2F5FBF" +theme[selected_bg]="#ABA898" +theme[selected_fg]="#252D3B" +theme[inactive_fg]="#767E8D" +theme[graph_text]="#4A5568" +theme[meter_bg]="#E8E5DB" +theme[proc_misc]="#46689E" +theme[cpu_box]="#2F5FBF" +theme[mem_box]="#3E7449" +theme[net_box]="#46689E" +theme[proc_box]="#E8E5DB" +theme[div_line]="#ABA898" +theme[temp_start]="#3E7449" +theme[temp_mid]="#8D6110" +theme[temp_end]="#A84048" +theme[cpu_start]="#3E7449" +theme[cpu_mid]="#8D6110" +theme[cpu_end]="#A84048" +theme[free_start]="#3E7449" +theme[used_start]="#8D6110" +theme[download_start]="#2F5FBF" +theme[upload_start]="#46689E" diff --git a/themes/executive-ivory/preview.png b/themes/executive-ivory/preview.png new file mode 100644 index 0000000..658a8b8 Binary files /dev/null and b/themes/executive-ivory/preview.png differ diff --git a/themes/executive-ivory/rofi.rasi b/themes/executive-ivory/rofi.rasi new file mode 100644 index 0000000..506a4d6 --- /dev/null +++ b/themes/executive-ivory/rofi.rasi @@ -0,0 +1,125 @@ +/** + * Executive Ivory — rofi whole-swap (themes//rofi.rasi). + * Identity: a flat, sharp-cornered "control panel". No zebra, no glow — + * a solid ivory window, a recessed surface inputbar, and one accent edge + * marking the selected row. The `configuration {}` block is omitted on + * purpose — modi/terminal/show-icons come from modules/home/rofi.nix. + * Element structure mirrors the generated theme so the theme-grid + * picker's per-invocation -theme-str (vertical cards) still lays out. + */ + +* { + base: #F2F0E9; + surface: #E8E5DB; + overlay: #ABA898; + text: #252D3B; + subtext: #4A5568; + muted: #767E8D; + accent: #2F5FBF; + accentAlt: #46689E; + + font: "Inter 13"; + background-color: transparent; + text-color: @text; +} + +window { + background-color: @base; + border: 1px; + border-color: @overlay; + border-radius: 4px; + width: calc( 84ch min 65% ); + location: center; + anchor: center; + padding: 12px; +} + +mainbox { + background-color: transparent; + children: [ inputbar, message, listview ]; + spacing: 10px; +} + +inputbar { + children: [ prompt, entry ]; + background-color: @surface; + text-color: @text; + border: 1px; + border-color: @overlay; + border-radius: 4px; + padding: 10px 14px; + spacing: 10px; +} + +prompt { text-color: @accent; } + +entry { + text-color: @text; + cursor: text; + placeholder: "Type to filter…"; + placeholder-color: @muted; +} + +listview { + background-color: transparent; + columns: 1; + lines: 8; + dynamic: true; + scrollbar: true; + spacing: 4px; + padding: 4px 0px 0px 0px; +} + +element { + background-color: transparent; + text-color: @text; + orientation: horizontal; + border-radius: 4px; + padding: 9px 14px; + spacing: 12px; +} + +element normal.normal, +element alternate.normal { + background-color: transparent; +} + +/* The one highlight: a solid accent-tinted row with an accent edge. */ +element selected.normal { + background-color: #2F5FBF26; + text-color: @text; + border: 0px 0px 0px 3px; + border-color: @accent; +} + +element-icon { + background-color: transparent; + size: 36px; + cursor: inherit; +} + +element-text { + background-color: transparent; + text-color: inherit; + highlight: bold; + vertical-align: 0.5; +} + +message { padding: 0px; } + +textbox { + background-color: @surface; + text-color: @text; + border: 1px; + border-color: @overlay; + border-radius: 4px; + padding: 9px 14px; +} + +scrollbar { + width: 4px; + handle-width: 4px; + handle-color: @accent; + background-color: @surface; + border: 0px; +} diff --git a/themes/executive-ivory/waybar.css b/themes/executive-ivory/waybar.css new file mode 100644 index 0000000..a7111f9 --- /dev/null +++ b/themes/executive-ivory/waybar.css @@ -0,0 +1,207 @@ +/* + * Executive Ivory — Waybar whole-swap (themes//waybar.css). + * + * A theme waybar.css replaces the ENTIRE generated stylesheet and is read + * raw (no palette is prepended), so this file MUST define its own colors. + * Identity: a solid, non-transparent, edge-to-edge status strip — no + * floating island, sharp corners, tight modules, and a single accent + * underline marking the active workspace. Companion: waybar.jsonc. + */ + +@define-color base #F2F0E9; +@define-color mantle #DCD9CE; +@define-color surface #E8E5DB; +@define-color overlay #ABA898; +@define-color text #252D3B; +@define-color subtext #4A5568; +@define-color muted #767E8D; +@define-color accent #2F5FBF; +@define-color accentAlt #46689E; +@define-color good #3E7449; +@define-color warn #8D6110; +@define-color bad #A84048; + +/* NB: this `*` reset reaches the SNI tray menus Waybar hosts too (its + stylesheet applies process-wide, at a priority user gtk.css cannot + out-rank). The menu block right below undoes the damage — keep the two + in sync. Do NOT scope `*` to window#waybar instead: the id's + specificity would beat the class rules below and wreck the bar. */ +* { + /* Mono Nerd face first for status glyphs: proportional "Symbols Nerd + Font" has tight right bearings that make icon+percentage collide. */ + font-family: "Symbols Nerd Font Mono", "Inter", "JetBrainsMono Nerd Font", sans-serif; + font-size: 13px; + font-weight: 500; + border: none; + border-radius: 0; + min-height: 0; +} + +/* ── Tray menus (nm-applet & co live in Waybar's process) ───────────── + Undo the `*` reset for them: same stylesheet, higher specificity. + Arrows/checks are CSS-sized nodes — min-height 0 makes them invisible; + separators die the same way; the glyph-first face reads wrong in text + menus. */ +menu, menu * { font-family: "Inter", sans-serif; } +menu menuitem arrow { min-width: 16px; min-height: 16px; } +menu check, menu radio { min-width: 14px; min-height: 14px; } +menu separator { + min-height: 1px; + margin: 5px 0; + background: alpha(@text, 0.2); +} + +/* Solid bar, crisp edge against the content below. */ +window#waybar { + background: @base; + border-bottom: 1px solid @overlay; + color: @text; +} + +.modules-left, +.modules-center, +.modules-right { + margin: 0; + padding: 0; +} + +/* Uniform module rhythm; groups get a wider breath below. */ +#custom-nomarchy, +#clock, +#custom-recording, +#idle_inhibitor, +#custom-nightlight, +#custom-airplane, +#language, +#custom-updates, +#pulseaudio, +#custom-powerprofile, +#battery, +#custom-vpn, +#custom-doctor, +#custom-notification, +#tray, +#custom-powermenu { + color: @text; + padding: 0 11px; + margin: 0; +} + +/* Group heads — a wider gap before each functional cluster of the + right side (media/toggles · stats · status). Self-hiding heads + (e.g. no battery on a desktop) degrade to the uniform spacing. */ +#pulseaudio, +#battery, +#custom-vpn { margin-left: 6px; } + +/* ── Menu launcher — the branded Nomarchy mark ─────────────────────── + The mark lives at U+F000 in the dedicated "Nomarchy" font; pin the + family or the Nerd Font's glass glyph at the same codepoint wins. */ +#custom-nomarchy { + color: @accent; + font-family: Nomarchy; + font-size: 16px; + padding: 0 14px; +} +#custom-nomarchy:hover { + background: @surface; + color: @accentAlt; +} + +/* ── Workspaces — flat cells, active carries an accent underline ──── */ +#workspaces { padding: 0; margin: 0; } + +#workspaces button { + color: @subtext; + padding: 0 11px; + margin: 0; + border-bottom: 2px solid transparent; + transition: color 0.15s ease-in-out, background 0.15s ease-in-out; +} + +#workspaces button:hover { + background: @surface; + color: @text; + border-bottom: 2px solid @overlay; +} + +#workspaces button.active { + color: @text; + background: @surface; + border-bottom: 2px solid @accent; +} + +#workspaces button.urgent { + color: @bad; + border-bottom: 2px solid @bad; +} + +/* ── Clock — unified time · date in one module ───────────────────── */ +#clock { + color: @text; + font-weight: 600; + font-family: "Inter", "Symbols Nerd Font Mono", sans-serif; +} + +/* ── Status cluster: neutral by default, semantic on state ───────── */ +#custom-recording.recording { color: @bad; } + +#idle_inhibitor.activated { color: @warn; } + +#custom-nightlight.on { color: @warn; } +#custom-airplane.on { color: @warn; } + +#custom-updates.available { color: @accent; } + +/* Icon-only status modules carry no text, so they don't get the 13pt + Pango icon span the icon+text modules (volume/battery/language) use — + bump their font-size to match, or these glyphs read smaller than their + neighbours. */ +#custom-recording, +#custom-nightlight, +#custom-airplane, +#custom-updates, +#custom-vpn, +#custom-doctor, +#custom-notification { font-size: 17px; } +/* Speedometer + caffeine cup render small in their em box — a touch more. */ +#custom-powerprofile, +#idle_inhibitor { font-size: 18px; } + +#pulseaudio.muted { color: @muted; } + +#battery.charging { color: @good; } +#battery.warning:not(.charging) { color: @warn; } +#battery.critical:not(.charging) { + color: @bad; + border-bottom: 2px solid @bad; +} + +#custom-vpn.on { color: @good; } + +/* Doctor is only rendered when something is ✖, so always the alert. */ +#custom-doctor { color: @bad; } + +#custom-notification.notification { color: @accent; } +#custom-notification.dnd-none, +#custom-notification.dnd-notification, +#custom-notification.inhibited-none, +#custom-notification.inhibited-notification { color: @muted; } + +#tray { color: @text; } + +#custom-powermenu { color: @subtext; } +#custom-powermenu:hover { + background: @surface; + color: @bad; +} + +/* ── Tooltips ─────────────────────────────────────────────────────── */ +tooltip { + background: @surface; + border: 1px solid @overlay; + border-radius: 4px; +} +tooltip label { + color: @text; +} diff --git a/themes/executive-ivory/waybar.jsonc b/themes/executive-ivory/waybar.jsonc new file mode 100644 index 0000000..b2326ec --- /dev/null +++ b/themes/executive-ivory/waybar.jsonc @@ -0,0 +1,182 @@ +{ + "margin-top": 0, + "margin-left": 0, + "margin-bottom": 0, + "margin-right": 0, + "height": 34, + "layer": "bottom", + "position": "top", + "spacing": 0, + "reload_style_on_change": true, + "modules-left": [ + "custom/nomarchy", + "hyprland/workspaces" + ], + "modules-center": [ + "clock" + ], + "modules-right": [ + "custom/recording", + "idle_inhibitor", + "custom/nightlight", + "hyprland/language", + "custom/updates", + "pulseaudio", + "custom/powerprofile", + "battery", + "custom/vpn", + "custom/airplane", + "custom/doctor", + "custom/notification", + "tray", + "custom/powermenu" + ], + "custom/nomarchy": { + "interval": "once", + "format": "\uf000", + "on-click": "nomarchy-menu", + "tooltip-format": "Nomarchy menu" + }, + "hyprland/workspaces": { + "disable-scroll": true, + "all-outputs": true, + "on-click": "activate", + "on-scroll-up": "hyprctl dispatch workspace r+1", + "on-scroll-down": "hyprctl dispatch workspace r-1" + }, + "clock": { + "format": "{:%H:%M \u00b7 %a %d %b}", + "on-click": "nomarchy-calendar", + "tooltip": true, + "tooltip-format": "{:%A, %d %B %Y\n%Z (UTC%z)}" + }, + "custom/recording": { + "return-type": "json", + "interval": 10, + "signal": 8, + "exec": "nomarchy-record status", + "on-click": "nomarchy-record stop" + }, + "idle_inhibitor": { + "format": "{icon}", + "format-icons": { + "activated": " \udb80\udd76 ", + "deactivated": " \udb83\udfaa " + } + }, + "custom/nightlight": { + "return-type": "json", + "interval": 3, + "exec": "nomarchy-nightlight status", + "on-click": "nomarchy-nightlight toggle" + }, + "hyprland/language": { + "format": "\udb80\udf0c {short}", + "tooltip": false + }, + "custom/updates": { + "return-type": "json", + "interval": 1800, + "signal": 9, + "exec": "nomarchy-updates status", + "on-click": "nomarchy-updates upgrade-window" + }, + "pulseaudio": { + "scroll-step": 5, + "format": "{icon}{volume}%", + "format-bluetooth": "{icon}\uf294 {volume}%", + "format-bluetooth-muted": "\uf6a9 {icon}\uf294", + "format-muted": "\uf6a9 muted", + "format-icons": { + "headphone": "\uf025 ", + "hands-free": "\uf025 ", + "headset": "\uf025 ", + "phone": "\uf095 ", + "portable": "\uf095 ", + "car": "\uf1b9 ", + "default": [ + "\uf026 ", + "\uf027 ", + "\uf028 " + ] + }, + "on-click": "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle", + "on-click-right": "pwvucontrol", + "tooltip-format": "{desc} | {volume}%" + }, + "custom/powerprofile": { + "return-type": "json", + "interval": 5, + "exec": "nomarchy-powerprofile-status", + "on-click": "nomarchy-menu powermgmt" + }, + "battery": { + "interval": 30, + "states": { + "warning": 25, + "critical": 10 + }, + "format": "{icon}{capacity}%", + "format-charging": "\uf0e7 {capacity}%", + "format-plugged": "\uf1e6 {capacity}%", + "tooltip-format-plugged": "Plugged in, not charging \u2014 held at {capacity}% by the battery charge cap\nCharging resumes ~10% below the cap \u00b7 click to adjust", + "format-icons": [ + "\uf244 ", + "\uf243 ", + "\uf242 ", + "\uf241 ", + "\uf240 " + ], + "on-click": "nomarchy-menu powermgmt", + "tooltip-format": "Battery status" + }, + "custom/vpn": { + "return-type": "json", + "interval": 5, + "exec": "nomarchy-vpn-status", + "on-click": "nomarchy-vpn" + }, + "custom/doctor": { + "return-type": "json", + "format": "{}", + "interval": 300, + "signal": 10, + "exec": "nomarchy-doctor-status", + "on-click": "nomarchy-menu doctor" + }, + "custom/notification": { + "format": "{icon}", + "return-type": "json", + "exec": "swaync-client -swb", + "exec-if": "which swaync-client", + "escape": true, + "tooltip": true, + "on-click": "swaync-client -t -sw", + "on-click-right": "swaync-client -d -sw", + "format-icons": { + "none": "\udb80\udc9c", + "notification": "\udb80\udc9a", + "dnd-none": "\udb80\udc9b", + "dnd-notification": "\udb80\udc9b", + "inhibited-none": "\udb80\udc9b", + "inhibited-notification": "\udb80\udc9b", + "dnd-inhibited-none": "\udb80\udc9b", + "dnd-inhibited-notification": "\udb80\udc9b" + } + }, + "tray": { + "spacing": 8 + }, + "custom/powermenu": { + "format": "\uf011", + "on-click": "nomarchy-menu power", + "tooltip": false + }, + "custom/airplane": { + "return-type": "json", + "interval": 5, + "signal": 11, + "exec": "nomarchy-airplane status", + "on-click": "nomarchy-airplane toggle" + } +}