git.lucas.co / cce-system-interface
system settings
git clone https://git.lucas.co/cce-system-interface.git

commit8d289c380f32611c1de0945642f86cff57ff1a46
parent01f8452ec0
authorLucas Galante <[email protected]>
date2026-06-01 06:56
Add controls for status separators, underline, and padding to the status interface configuration page

 Cargo.lock                 |   2 +
 src/main.rs                | 333 +++++++++++++++++++++++++++++++++------------
 src/pages/colors.rs        | 240 ++++++++++++++++++++++----------
 src/pages/display.rs       |   4 +-
 src/pages/input.rs         |   6 +-
 src/pages/layout.rs        | 101 +++++++-------
 src/pages/notifications.rs | 123 ++++++++++++++++-
 src/pages/status.rs        | 216 ++++++++++++++++++++++++++++-
 src/pages/typeface.rs      |  18 ++-
 9 files changed, 811 insertions(+), 232 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 08b9097..ce5956a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -358,7 +358,9 @@ dependencies = [
  "serde",
  "smithay-client-toolkit",
  "tokio",
+ "wayland-backend",
  "wayland-client",
+ "wayland-scanner",
  "wgpu",
  "xkeysym",
 ]
diff --git a/src/main.rs b/src/main.rs
index 281a0f1..b844821 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
 use std::sync::Arc;
 
 use clear_ui::color;
-use clear_ui::widget::{Spinbox, Widget, Finger};
+use clear_ui::widget::{Spinbox, Widget, Finger, Slider, hover_animation};
 use glyphon::{
     Attrs, Buffer, Cache, FontSystem, Metrics, Resolution, SwashCache, TextArea, TextAtlas,
     TextBounds, TextRenderer, Viewport,
@@ -165,7 +165,6 @@ struct AppWidget {
 
 #[derive(Clone)]
 enum WidgetKind {
-    PageButton(Page),
     ActionButton(AppAction),
     Static,
 }
@@ -237,8 +236,10 @@ struct SystemInterface {
     needs_rebuild: bool,
     scroll_y: f32,
     max_scroll_y: f32,
+    opacity_dragging: bool,
     page_root_container: clear_ui::widget::Container,
     page_sec_containers: Vec<clear_ui::widget::Container>,
+    paginator: clear_ui::widget::Paginator,
     sans_serif_family: String,
     serif_family: String,
     monospace_family: String,
@@ -273,7 +274,7 @@ impl SystemInterface {
         });
         let wgpu_surface = instance.create_surface(wayland_handle).expect("surface");
         let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
-            power_preference: wgpu::PowerPreference::HighPerformance,
+            power_preference: wgpu::PowerPreference::LowPower,
             compatible_surface: Some(&wgpu_surface),
             force_fallback_adapter: false,
         }).await.expect("adapter");
@@ -451,6 +452,9 @@ impl SystemInterface {
 
         let (sans_family, serif_family, monospace_family, _, _, _, _) = pages::typeface::read_preferred_fonts();
 
+        let pages_names = Page::ALL.iter().map(|p| p.label().to_string()).collect::<Vec<_>>();
+        let paginator = clear_ui::widget::Paginator::new(140.0, pages_names);
+
         let mut this = Self {
             window, surface, wgpu_surface, device, queue, config, render_pipeline,
             vertex_buffer, vertex_count: 0,
@@ -468,8 +472,10 @@ impl SystemInterface {
             needs_rebuild: true,
             scroll_y: 0.0,
             max_scroll_y: 0.0,
+            opacity_dragging: false,
             page_root_container: clear_ui::widget::Container::new(),
             page_sec_containers: Vec::new(),
+            paginator,
             sans_serif_family: sans_family,
             serif_family,
             monospace_family,
@@ -497,59 +503,46 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         let mut text_items = Vec::new();
         let mut page_buttons = Vec::new();
 
-        let sb_w = self.sidebar_width * s;
-        let hdr_h = self.header_height * s;
-        let st_h = self.status_height * s;
+        clear_ui::widget::hover_animation::reset_frame_registration();
+        clear_ui::widget::hover_animation::set_scroll_offset(self.scroll_y);
+        clear_ui::widget::hover_animation::set_cursor_pos(self.cursor_x / s, self.cursor_y / s);
 
-        // Sidebar bg
-        widgets.push(AppWidget {
-            x: 0.0, y: hdr_h, w: sb_w, h: sh - hdr_h - st_h,
-            color: [0.16, 0.16, 0.26, 1.0],
-            hover_color: [0.16, 0.16, 0.26, 1.0],
-            hovering: false, kind: WidgetKind::Static,
-        });
+        let lcx = self.sidebar_width;
+        let lcy = self.header_height;
+        let lcw = sw / s - self.sidebar_width;
+        let lch = sh / s - self.header_height - self.status_height;
+
+        let page_idx = Page::ALL.iter().position(|&p| p == self.app.current_page).unwrap_or(0);
+        self.paginator.set_selected_page(page_idx);
 
-        // Sidebar page buttons
-        let btn_h = 32.0 * s;
-        let btn_margin = 4.0 * s;
-        let total = Page::ALL.len() as f32;
-        let sb_h = sh - hdr_h - st_h;
-        let start_y = hdr_h + (sb_h - total * (btn_h + btn_margin)) / 2.0;
-        let start_y = start_y.max(hdr_h + 8.0 * s);
-
-        for (i, page) in Page::ALL.iter().enumerate() {
-            let active = *page == self.app.current_page;
-            let y = start_y + i as f32 * (btn_h + btn_margin);
-            let bg = if active { color::BUTTON_PRESS } else { [0.18, 0.18, 0.28, 1.0] };
-            let hov = if active { color::BUTTON_IDLE } else { [0.22, 0.22, 0.34, 1.0] };
+        let mut paginator_pc = PageContent::new();
+        clear_ui::layout::render_widget(&mut paginator_pc, &mut self.paginator, 0.0, 0.0, sw / s, sh / s);
+
+        for (c, x, y, w, h) in &paginator_pc.rects {
             widgets.push(AppWidget {
-                x: 6.0 * s, y, w: sb_w - 12.0 * s, h: btn_h,
-                color: bg, hover_color: hov,
-                hovering: false,
-                kind: WidgetKind::PageButton(*page),
+                x: *x * s, y: *y * s, w: *w * s, h: *h * s,
+                color: *c, hover_color: *c,
+                hovering: false, kind: WidgetKind::Static,
             });
+        }
+        for (t, size, x, y, tc, font_opt) in &paginator_pc.texts {
             text_items.push(TextItem {
-                buffer: make_text_buffer(&mut self.font_system, page.label(), 12.0 * s),
-                x: 16.0 * s, y: y + 9.0 * s,
-                color: glyphon::Color::rgb(0x33, 0x33, 0x4a),
+                buffer: make_text_buffer_with_font(
+                    &mut self.font_system,
+                    t,
+                    *size * s,
+                    font_opt.as_deref(),
+                    &self.sans_serif_family,
+                    &self.serif_family,
+                    &self.monospace_family,
+                ),
+                x: *x * s, y: *y * s,
+                color: glyphon::Color::rgb(
+                    (tc[0] * 255.0) as u8, (tc[1] * 255.0) as u8, (tc[2] * 255.0) as u8,
+                ),
             });
         }
 
-        // Content area
-        let lcx = self.sidebar_width;
-        let lcy = self.header_height;
-        let lcw = sw / s - self.sidebar_width;
-        let lch = sh / s - self.header_height - self.status_height;
-        let p_cx = lcx * s;
-        let p_cy = lcy * s;
-        let p_cw = lcw * s;
-        let p_ch = lch * s;
-        widgets.push(AppWidget {
-            x: p_cx, y: p_cy, w: p_cw, h: p_ch,
-            color: color::CONTENT_BG, hover_color: color::CONTENT_BG,
-            hovering: false, kind: WidgetKind::Static,
-        });
-
         // Page content in LOGICAL coordinates, then scale to physical
         let mut pc = self.render_page_content(lcx, lcy, lcw, lch);
 
@@ -709,6 +702,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         }
 
         self.app.notifications.duration_spinbox.clear_children(); self.app.notifications.duration_spinbox.set_parent(None);
+        self.app.notifications.opacity_slider.clear_children(); self.app.notifications.opacity_slider.set_parent(None);
 
         self.app.input.rate_spinbox.clear_children(); self.app.input.rate_spinbox.set_parent(None);
         self.app.input.delay_spinbox.clear_children(); self.app.input.delay_spinbox.set_parent(None);
@@ -728,6 +722,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         }
 
         self.app.display.brightness_spinbox.clear_children(); self.app.display.brightness_spinbox.set_parent(None);
+        self.app.status.padding_spinbox.clear_children(); self.app.status.padding_spinbox.set_parent(None);
 
         use clear_ui::widget::focus::link_parent_child;
         match self.app.current_page {
@@ -765,34 +760,21 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 link_parent_child(&mut self.page_root_container, &mut self.app.network.wifi_list_box.scroll_box);
             }
             Page::Layout => {
-                self.page_sec_containers.resize_with(6, clear_ui::widget::Container::new);
+                self.page_sec_containers.resize_with(3, clear_ui::widget::Container::new);
                 
-                for i in 0..6 {
+                for i in 0..3 {
                     link_parent_child(&mut self.page_root_container, &mut self.page_sec_containers[i]);
                 }
                 
-                if !self.app.layout.spinboxes.is_empty() {
-                    link_parent_child(&mut self.page_sec_containers[0], &mut self.app.layout.spinboxes[0]);
-                }
-                if self.app.layout.spinboxes.len() > 1 {
-                    link_parent_child(&mut self.page_sec_containers[1], &mut self.app.layout.spinboxes[1]);
+                for sb in &mut self.app.layout.spinboxes {
+                    link_parent_child(&mut self.page_sec_containers[0], sb);
                 }
+                
                 link_parent_child(&mut self.page_sec_containers[1], &mut self.app.layout.cascade_offset_spinbox);
                 link_parent_child(&mut self.page_sec_containers[1], &mut self.app.layout.edge_gap_spinbox);
                 link_parent_child(&mut self.page_sec_containers[1], &mut self.app.layout.top_gap_spinbox);
                 
-                if self.app.layout.spinboxes.len() > 2 {
-                    link_parent_child(&mut self.page_sec_containers[2], &mut self.app.layout.spinboxes[2]);
-                }
-                if self.app.layout.spinboxes.len() > 3 {
-                    link_parent_child(&mut self.page_sec_containers[3], &mut self.app.layout.spinboxes[3]);
-                }
-                if self.app.layout.spinboxes.len() > 4 {
-                    link_parent_child(&mut self.page_sec_containers[4], &mut self.app.layout.spinboxes[4]);
-                }
-                if self.app.layout.spinboxes.len() > 5 {
-                    link_parent_child(&mut self.page_sec_containers[5], &mut self.app.layout.spinboxes[5]);
-                }
+                link_parent_child(&mut self.page_sec_containers[2], &mut self.app.layout.transition_duration_spinbox);
             }
             Page::Colors => {
                 for cs in &mut self.app.colors.color_selectors {
@@ -801,6 +783,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             }
             Page::Notifications => {
                 link_parent_child(&mut self.page_root_container, &mut self.app.notifications.duration_spinbox);
+                link_parent_child(&mut self.page_root_container, &mut self.app.notifications.opacity_slider);
             }
             Page::Input => {
                 self.page_sec_containers.resize_with(4, clear_ui::widget::Container::new);
@@ -837,9 +820,27 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             Page::Display => {
                 link_parent_child(&mut self.page_root_container, &mut self.app.display.brightness_spinbox);
             }
+            Page::Status => {
+                link_parent_child(&mut self.page_root_container, &mut self.app.status.padding_spinbox);
+            }
             _ => {}
         }
 
+        // Draw global hover highlight if active
+        clear_ui::widget::hover_animation::post_render_check();
+        if let Some((qx, qy, qw, qh, qc)) = clear_ui::widget::hover_animation::get_quad() {
+            widgets.push(AppWidget {
+                x: qx * s,
+                y: (qy - self.scroll_y) * s,
+                w: qw * s,
+                h: qh * s,
+                color: qc,
+                hover_color: qc,
+                hovering: false,
+                kind: WidgetKind::Static,
+            });
+        }
+
         // Render context menu overlay if visible
         if clear_ui::widget::context_menu::is_visible() {
             let cx = clear_ui::widget::context_menu::x();
@@ -886,6 +887,8 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             }
         }
 
+
+
         self.widgets = widgets;
         self.text_items = text_items;
         self.page_buttons = page_buttons;
@@ -973,6 +976,27 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         }
     }
 
+    fn tick(&mut self, dt: f32) -> bool {
+        let mut needs_redraw = false;
+        if hover_animation::tick(dt) {
+            needs_redraw = true;
+            self.needs_rebuild = true;
+        }
+        if self.paginator.tick(dt) {
+            needs_redraw = true;
+            self.needs_rebuild = true;
+        }
+        if let Some(root_ptr) = self.get_page_root_widget() {
+            unsafe {
+                if (*root_ptr).tick(dt) {
+                    needs_redraw = true;
+                    self.needs_rebuild = true;
+                }
+            }
+        }
+        needs_redraw
+    }
+
     fn poll_background_updates(&mut self) {
         use pages::*;
         while let Ok(s) = self.rx_audio.try_recv() {
@@ -1098,10 +1122,10 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         self.cursor_x = x;
         self.cursor_y = y;
         let s = self.scale_factor as f32;
+        let lx_no_scroll = x / s;
+        let ly_no_scroll = y / s;
         
         if clear_ui::widget::context_menu::is_visible() {
-            let lx_no_scroll = x / s;
-            let ly_no_scroll = y / s;
             if clear_ui::widget::context_menu::cursor_moved(lx_no_scroll, ly_no_scroll) {
                 self.needs_rebuild = true;
                 return true;
@@ -1111,7 +1135,11 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
 
         let lx = self.cursor_x / s;
         let ly = self.cursor_y / s + self.scroll_y;
+        clear_ui::widget::hover_animation::set_cursor_pos(lx, ly_no_scroll);
         let mut changed = false;
+        if self.paginator.cursor_moved(lx_no_scroll, ly_no_scroll) {
+            changed = true;
+        }
         for w in &mut self.widgets {
             let was = w.hovering;
             w.hovering = self.cursor_x >= w.x && self.cursor_x <= w.x + w.w
@@ -1136,6 +1164,9 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             if self.app.layout.top_gap_spinbox.cursor_moved(lx, ly) {
                 changed = true;
             }
+            if self.app.layout.transition_duration_spinbox.cursor_moved(lx, ly) {
+                changed = true;
+            }
         }
         if self.app.current_page == Page::Colors {
             for cp in &mut self.app.colors.color_selectors {
@@ -1215,7 +1246,11 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 }
             }
         }
-        if self.app.current_page == Page::Notifications {
+        if self.opacity_dragging && self.app.current_page == Page::Notifications {
+            if self.app.notifications.opacity_slider.drag_update(lx, ly) {
+                changed = true;
+            }
+        } else if self.app.current_page == Page::Notifications {
             if self.app.notifications.enable_toggle.cursor_moved(lx, ly) {
                 changed = true;
             }
@@ -1225,6 +1260,9 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             if self.app.notifications.duration_spinbox.cursor_moved(lx, ly) {
                 changed = true;
             }
+            if self.app.notifications.opacity_slider.cursor_moved(lx, ly) {
+                changed = true;
+            }
         }
         if self.app.current_page == Page::Hardware {
             if self.app.hardware.cpu_label.cursor_moved(lx, ly) {
@@ -1246,6 +1284,15 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             if self.app.status.size_label.cursor_moved(lx, ly) {
                 changed = true;
             }
+            if self.app.status.separators_toggle.cursor_moved(lx, ly) {
+                changed = true;
+            }
+            if self.app.status.underline_toggle.cursor_moved(lx, ly) {
+                changed = true;
+            }
+            if self.app.status.padding_spinbox.cursor_moved(lx, ly) {
+                changed = true;
+            }
         }
         if self.app.current_page == Page::Typefaces {
             if self.app.typeface.sans_box.cursor_moved(lx, ly) {
@@ -1336,6 +1383,19 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             }
         }
 
+        if self.paginator.mouse_input(button, state, lx_no_scroll, ly_no_scroll) {
+            if self.paginator.take_click() {
+                let idx = self.paginator.selected_page();
+                if idx < Page::ALL.len() {
+                    clear_ui::widget::focus::clear_focus();
+                    self.app.current_page = Page::ALL[idx];
+                    self.scroll_y = 0.0;
+                }
+            }
+            self.needs_rebuild = true;
+            return true;
+        }
+
         if button != clear_ui::widget::MouseButton::Left && button != clear_ui::widget::MouseButton::Right { return false; }
         if button == clear_ui::widget::MouseButton::Left && state == clear_ui::widget::ElementState::Released {
             let (px, py) = (self.cursor_x, self.cursor_y);
@@ -1346,19 +1406,6 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                     return true;
                 }
             }
-            for w in &self.widgets {
-                if px >= w.x && px <= w.x + w.w && py >= w.y && py <= w.y + w.h {
-                    if let WidgetKind::PageButton(p) = &w.kind {
-                        if self.app.current_page != *p {
-                            clear_ui::widget::focus::clear_focus();
-                            self.app.current_page = *p;
-                            self.scroll_y = 0.0;
-                            self.needs_rebuild = true;
-                            return true;
-                        }
-                    }
-                }
-            }
         }
         let lx = self.cursor_x / s;
         let ly = self.cursor_y / s + self.scroll_y;
@@ -1374,6 +1421,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                     if self.app.layout.cascade_offset_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
                     if self.app.layout.edge_gap_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
                     if self.app.layout.top_gap_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
+                    if self.app.layout.transition_duration_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
                 }
                 Page::Colors => {
                     for cp in &mut self.app.colors.color_selectors {
@@ -1391,6 +1439,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 }
                 Page::Notifications => {
                     if self.app.notifications.duration_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
+                    if self.app.notifications.opacity_slider.hit_test(lx, ly) { clicked_any_focusable = true; }
                 }
                 Page::Audio => {
                     for sb in &mut self.app.audio.sink_spinboxes {
@@ -1414,6 +1463,7 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 Page::Status => {
                     if self.app.status.status_label.hit_test(lx, ly) { clicked_any_focusable = true; }
                     if self.app.status.size_label.hit_test(lx, ly) { clicked_any_focusable = true; }
+                    if self.app.status.padding_spinbox.hit_test(lx, ly) { clicked_any_focusable = true; }
                 }
                 Page::Typefaces => {
                     let tf = &mut self.app.typeface;
@@ -1489,6 +1539,14 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                     pages::layout::LayoutMessage::SetTopGap(sb.value as u16)
                 ));
             }
+            let sb = &mut self.app.layout.transition_duration_spinbox;
+            if !sb.hit_test(lx, ly) { sb.unfocus(); }
+            let old = sb.value;
+            if sb.mouse_input(button, state, lx, ly) && sb.value != old {
+                actions.push(AppAction::Layout(
+                    pages::layout::LayoutMessage::SetTransitionDuration(sb.value as u16)
+                ));
+            }
         }
         if state == clear_ui::widget::ElementState::Pressed && self.app.current_page == Page::Colors {
             for (i, cp) in self.app.colors.color_selectors.iter_mut().enumerate() {
@@ -1497,16 +1555,26 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 cp.mouse_input(button, state, lx, ly);
                 if cp.take_click() {
                     actions.push(AppAction::Colors(match i {
-                        0 => pages::colors::ColorsMessage::PickLowColor,
+                        0 => pages::colors::ColorsMessage::PickPageLowColor,
                         1 => pages::colors::ColorsMessage::PickHighColor,
-                        _ => pages::colors::ColorsMessage::PickDisabledColor,
+                        2 => pages::colors::ColorsMessage::PickVisualGuides,
+                        3 => pages::colors::ColorsMessage::PickDisabledColor,
+                        4 => pages::colors::ColorsMessage::PickSeparatorColor,
+                        5 => pages::colors::ColorsMessage::PickSliderTrackColor,
+                        6 => pages::colors::ColorsMessage::PickColorBordersColor,
+                        _ => pages::colors::ColorsMessage::PickLowColor,
                     }));
                 }
                 if cp.color != old {
                     actions.push(AppAction::Colors(match i {
-                        0 => pages::colors::ColorsMessage::SetLowColor(cp.color),
+                        0 => pages::colors::ColorsMessage::SetPageLowColor(cp.color),
                         1 => pages::colors::ColorsMessage::SetHighColor(cp.color),
-                        _ => pages::colors::ColorsMessage::SetDisabledColor(cp.color),
+                        2 => pages::colors::ColorsMessage::SetVisualGuidesColor(cp.color),
+                        3 => pages::colors::ColorsMessage::SetDisabledColor(cp.color),
+                        4 => pages::colors::ColorsMessage::SetSeparatorColor(cp.color),
+                        5 => pages::colors::ColorsMessage::SetSliderTrackColor(cp.color),
+                        6 => pages::colors::ColorsMessage::SetColorBordersColor(cp.color),
+                        _ => pages::colors::ColorsMessage::SetLowColor(cp.color),
                     }));
                 }
             }
@@ -1617,6 +1685,24 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             if toggle.take_click() {
                 actions.push(AppAction::Notifications(pages::notifications::NotificationsMessage::ToggleBell));
             }
+            let slider = &mut self.app.notifications.opacity_slider;
+            if button == clear_ui::widget::MouseButton::Left {
+                if state == clear_ui::widget::ElementState::Pressed {
+                    if slider.hit_test(lx, ly) {
+                        slider.drag_begin(lx, ly);
+                        self.opacity_dragging = true;
+                        self.needs_rebuild = true;
+                    }
+                } else if state == clear_ui::widget::ElementState::Released {
+                    if self.opacity_dragging {
+                        self.opacity_dragging = false;
+                        slider.drag_end();
+                        let val = slider.value() as f32 / 100.0;
+                        actions.push(AppAction::Notifications(pages::notifications::NotificationsMessage::SetOpacity(val)));
+                        self.needs_rebuild = true;
+                    }
+                }
+            }
         }
         if state == clear_ui::widget::ElementState::Pressed && self.app.current_page == Page::Audio {
             for (i, sb) in self.app.audio.sink_spinboxes.iter_mut().enumerate() {
@@ -1670,6 +1756,26 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
             let lbl2 = &mut self.app.status.size_label;
             if !lbl2.hit_test(lx, ly) { lbl2.unfocus(); }
             lbl2.mouse_input(button, state, lx, ly);
+
+            let sb = &mut self.app.status.padding_spinbox;
+            if !sb.hit_test(lx, ly) { sb.unfocus(); }
+            let old = sb.value;
+            if sb.mouse_input(button, state, lx, ly) && sb.value != old {
+                actions.push(AppAction::Status(pages::status::StatusMessage::SetPadding(sb.value as u16)));
+            }
+        }
+        if self.app.current_page == Page::Status {
+            let toggle = &mut self.app.status.separators_toggle;
+            toggle.mouse_input(button, state, lx, ly);
+            if toggle.take_click() {
+                actions.push(AppAction::Status(pages::status::StatusMessage::ToggleSeparators));
+            }
+
+            let toggle2 = &mut self.app.status.underline_toggle;
+            toggle2.mouse_input(button, state, lx, ly);
+            if toggle2.take_click() {
+                actions.push(AppAction::Status(pages::status::StatusMessage::ToggleUnderline));
+            }
         }
         if self.app.current_page == Page::Typefaces {
             let tb = &mut self.app.typeface.sans_box;
@@ -2043,6 +2149,16 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 }
                 changed = true;
             }
+            let sb = &mut self.app.layout.transition_duration_spinbox;
+            let old = sb.value;
+            if sb.keyboard_input(event) {
+                if sb.value != old {
+                    actions.push(AppAction::Layout(
+                        pages::layout::LayoutMessage::SetTransitionDuration(sb.value as u16)
+                    ));
+                }
+                changed = true;
+            }
             for a in &actions {
                 self.handle_action(a);
             }
@@ -2059,9 +2175,14 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 if cp.keyboard_input(event) {
                     if cp.color != old {
                         actions.push(AppAction::Colors(match i {
-                            0 => pages::colors::ColorsMessage::SetLowColor(cp.color),
+                            0 => pages::colors::ColorsMessage::SetPageLowColor(cp.color),
                             1 => pages::colors::ColorsMessage::SetHighColor(cp.color),
-                            _ => pages::colors::ColorsMessage::SetDisabledColor(cp.color),
+                            2 => pages::colors::ColorsMessage::SetVisualGuidesColor(cp.color),
+                            3 => pages::colors::ColorsMessage::SetDisabledColor(cp.color),
+                            4 => pages::colors::ColorsMessage::SetSeparatorColor(cp.color),
+                            5 => pages::colors::ColorsMessage::SetSliderTrackColor(cp.color),
+                            6 => pages::colors::ColorsMessage::SetColorBordersColor(cp.color),
+                            _ => pages::colors::ColorsMessage::SetLowColor(cp.color),
                         }));
                     }
                     changed = true;
@@ -2166,6 +2287,19 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
                 return true;
             }
         }
+        if self.app.current_page == Page::Status {
+            let sb = &mut self.app.status.padding_spinbox;
+            let old = sb.value;
+            if sb.keyboard_input(event) {
+                let new_val = sb.value;
+                drop(sb);
+                if new_val != old {
+                    self.handle_action(&AppAction::Status(pages::status::StatusMessage::SetPadding(new_val as u16)));
+                }
+                self.needs_rebuild = true;
+                return true;
+            }
+        }
         if self.app.current_page == Page::Typefaces {
             if event.state == clear_ui::widget::ElementState::Pressed {
                 let is_down = match (&event.logical_key, event.ctrl) {
@@ -2422,13 +2556,22 @@ fn collect_popover_rects(w: &dyn clear_ui::widget::Widget, popovers: &mut Vec<(f
         });
 
         {
+            let r_clear = (self.app.colors.page_low_color[0] as f64 / 255.0).powf(2.2);
+            let g_clear = (self.app.colors.page_low_color[1] as f64 / 255.0).powf(2.2);
+            let b_clear = (self.app.colors.page_low_color[2] as f64 / 255.0).powf(2.2);
+
             let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
                 label: Some("Render Pass"),
                 color_attachments: &[Some(wgpu::RenderPassColorAttachment {
                     view: &view,
                     resolve_target: None,
                     ops: wgpu::Operations {
-                        load: wgpu::LoadOp::Clear(wgpu::Color { r: 0.06, g: 0.06, b: 0.08, a: 1.0 }),
+                        load: wgpu::LoadOp::Clear(wgpu::Color {
+                            r: r_clear,
+                            g: g_clear,
+                            b: b_clear,
+                            a: 1.0,
+                        }),
                         store: wgpu::StoreOp::Store,
                     },
                 })],
@@ -2947,6 +3090,7 @@ fn main() {
     const KEY_REPEAT_DELAY: std::time::Duration = std::time::Duration::from_millis(500);
     const KEY_REPEAT_INTERVAL: std::time::Duration = std::time::Duration::from_millis(50);
 
+    let mut last_tick = std::time::Instant::now();
     loop {
         event_loop
             .dispatch(std::time::Duration::from_millis(16), &mut app)
@@ -2954,7 +3098,16 @@ fn main() {
         if app.exit {
             break;
         }
+
+        let now = std::time::Instant::now();
+        let mut dt = now.duration_since(last_tick).as_secs_f32();
+        last_tick = now;
+        if dt > 0.1 {
+            dt = 0.1;
+        }
+
         if let Some(state) = &mut app.state {
+            state.tick(dt);
             state.poll_background_updates();
             if state.needs_rebuild {
                 app.redraw = true;
diff --git a/src/pages/colors.rs b/src/pages/colors.rs
index 9b7cf7e..6659c9b 100644
--- a/src/pages/colors.rs
+++ b/src/pages/colors.rs
@@ -4,12 +4,12 @@ use crate::app::PageContent;
 use clear_ui::layout::Section;
 use clear_ui::widget::ColorSelector;
 
-const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/ccec/config.toml";
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/clearwm-{}.sock", display),
-        Err(_) => "/tmp/clearwm.sock".to_string(),
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
     }
 }
 
@@ -18,8 +18,12 @@ pub struct ColorsState {
     pub low_color: [u8; 3],
     pub high_color: [u8; 3],
     pub disabled_color: [u8; 3],
+    pub separator_color: [u8; 3],
+    pub visual_guides_color: [u8; 3],
+    pub slider_track_color: [u8; 3],
+    pub page_low_color: [u8; 3],
+    pub color_borders_color: [u8; 3],
     pub color_selectors: Vec<ColorSelector>,
-    pub preset_colors: Vec<(&'static str, [u8; 3])>,
 }
 
 impl Default for ColorsState {
@@ -28,12 +32,21 @@ impl Default for ColorsState {
             low_color: [0x0a, 0x1a, 0x0e],
             high_color: [0x3e, 0x3e, 0x3e],
             disabled_color: [0x55, 0x55, 0x55],
+            separator_color: [124, 124, 137],
+            visual_guides_color: [0xff, 0x8c, 0x00],
+            slider_track_color: [116, 116, 128],
+            page_low_color: [71, 71, 81],
+            color_borders_color: [124, 124, 137],
             color_selectors: vec![
-                ColorSelector::new([0x0a, 0x1a, 0x0e]).with_label("Low Color"),
-                ColorSelector::new([0x3e, 0x3e, 0x3e]).with_label("High Color"),
-                ColorSelector::new([0x55, 0x55, 0x55]).with_label("Disabled"),
+                ColorSelector::new([71, 71, 81]).with_label("Low Color"), // 0: Pages - Low Color
+                ColorSelector::new([0x3e, 0x3e, 0x3e]).with_label("High Color"), // 1: Layout - High Color
+                ColorSelector::new([0xff, 0x8c, 0x00]).with_label("Visual Guides"), // 2: Layout - Visual Guides
+                ColorSelector::new([0x55, 0x55, 0x55]).with_label("Disabled"), // 3: Status - Disabled
+                ColorSelector::new([124, 124, 137]).with_label("Separators"), // 4: Status - Separators
+                ColorSelector::new([116, 116, 128]).with_label("Slider Track"), // 5: Controls - Slider Track
+                ColorSelector::new([124, 124, 137]).with_label("Borders"), // 6: Controls - Borders
+                ColorSelector::new([0x0a, 0x1a, 0x0e]).with_label("Low Color"), // 7: Layout - Low Color
             ],
-            preset_colors: preset_colors(),
         }
     }
 }
@@ -43,28 +56,23 @@ pub enum ColorsMessage {
     SetLowColor([u8; 3]),
     SetHighColor([u8; 3]),
     SetDisabledColor([u8; 3]),
+    SetSeparatorColor([u8; 3]),
+    SetVisualGuidesColor([u8; 3]),
+    SetSliderTrackColor([u8; 3]),
+    SetPageLowColor([u8; 3]),
+    SetColorBordersColor([u8; 3]),
     PickLowColor,
     PickHighColor,
     PickDisabledColor,
+    PickSeparatorColor,
+    PickVisualGuides,
+    PickSliderTrackColor,
+    PickPageLowColor,
+    PickColorBordersColor,
     Refreshed(ColorsState),
 }
 
-fn preset_colors() -> Vec<(&'static str, [u8; 3])> {
-    vec![
-        ("Black",       [0x00, 0x00, 0x00]),
-        ("Dark Gray",   [0x1a, 0x1a, 0x2e]),
-        ("Slate",       [0x2d, 0x2d, 0x3d]),
-        ("Dark Forest", [0x0a, 0x1a, 0x0e]),
-        ("Forest",      [0x1a, 0x2a, 0x1c]),
-        ("Dark Teal",   [0x0a, 0x1a, 0x1e]),
-        ("Navy",        [0x0a, 0x0f, 0x2e]),
-        ("Dark Wine",   [0x1e, 0x0a, 0x14]),
-        ("Dark Brown",  [0x1e, 0x16, 0x0e]),
-        ("Charcoal",    [0x22, 0x22, 0x22]),
-        ("Midnight",    [0x10, 0x10, 0x20]),
-        ("Deep Sea",    [0x06, 0x14, 0x1e]),
-    ]
-}
+
 
 pub fn read_colors_config() -> ColorsState {
     let content = fs::read_to_string(CONFIG_PATH).unwrap_or_default();
@@ -84,16 +92,35 @@ pub fn read_colors_config() -> ColorsState {
     
     let disabled = parse_color_from_key(&content, "disabled_color", [0x55, 0x55, 0x55]);
     
+    let separator = parse_color_from_key(&content, "status_separator_color", [124, 124, 137]);
+    
+    let visual_guides = parse_color_from_key(&content, "visual_guides_color", [0xff, 0x8c, 0x00]);
+    
+    let slider_track = parse_color_from_key(&content, "slider_track_color", [116, 116, 128]);
+
+    let page_low = parse_color_from_key(&content, "page_low_color", [71, 71, 81]);
+
+    let color_borders = parse_color_from_key(&content, "color_borders_color", [124, 124, 137]);
+    
     ColorsState {
         low_color: bg,
         high_color: border,
         disabled_color: disabled,
+        separator_color: separator,
+        visual_guides_color: visual_guides,
+        slider_track_color: slider_track,
+        page_low_color: page_low,
+        color_borders_color: color_borders,
         color_selectors: vec![
-            ColorSelector::new(bg).with_label("Low Color"),
-            ColorSelector::new(border).with_label("High Color"),
-            ColorSelector::new(disabled).with_label("Disabled"),
+            ColorSelector::new(page_low).with_label("Low Color"), // 0: Pages - Low Color
+            ColorSelector::new(border).with_label("High Color"), // 1: Layout - High Color
+            ColorSelector::new(visual_guides).with_label("Visual Guides"), // 2: Layout - Visual Guides
+            ColorSelector::new(disabled).with_label("Disabled"), // 3: Status - Disabled
+            ColorSelector::new(separator).with_label("Separators"), // 4: Status - Separators
+            ColorSelector::new(slider_track).with_label("Slider Track"), // 5: Controls - Slider Track
+            ColorSelector::new(color_borders).with_label("Borders"), // 6: Controls - Borders
+            ColorSelector::new(bg).with_label("Low Color"), // 7: Layout - Low Color
         ],
-        preset_colors: preset_colors(),
     }
 }
 
@@ -189,64 +216,100 @@ fn apply_disabled_color(rgb: [u8; 3]) {
     send_ipc_command(&format!("layout disabled_color #{:02x}{:02x}{:02x}", rgb[0], rgb[1], rgb[2]));
 }
 
+fn status_interface_reload() {
+    let _ = std::process::Command::new("pkill")
+        .args(["-f", "clear-status-interface"])
+        .status();
+    std::thread::sleep(std::time::Duration::from_millis(150));
+    send_ipc_command("spawn clear-status-interface");
+}
+
+fn apply_separator_color(rgb: [u8; 3]) {
+    let hex = format!("\"#{:02x}{:02x}{:02x}\"", rgb[0], rgb[1], rgb[2]);
+    write_config_value("status_separator_color", &hex);
+    send_ipc_command(&format!("layout status_separator_color #{:02x}{:02x}{:02x}", rgb[0], rgb[1], rgb[2]));
+    status_interface_reload();
+}
+
+fn apply_visual_guides_color(rgb: [u8; 3]) {
+    let hex = format!("\"#{:02x}{:02x}{:02x}\"", rgb[0], rgb[1], rgb[2]);
+    write_config_value("visual_guides_color", &hex);
+}
+
+fn apply_slider_track_color(rgb: [u8; 3]) {
+    let hex = format!("\"#{:02x}{:02x}{:02x}\"", rgb[0], rgb[1], rgb[2]);
+    write_config_value("slider_track_color", &hex);
+    let r = clear_ui::color::srgb_to_linear(rgb[0] as f32 / 255.0);
+    let g = clear_ui::color::srgb_to_linear(rgb[1] as f32 / 255.0);
+    let b = clear_ui::color::srgb_to_linear(rgb[2] as f32 / 255.0);
+    clear_ui::color::set_slider_track([r, g, b, 1.0]);
+}
+
+fn apply_page_low_color(rgb: [u8; 3]) {
+    let hex = format!("\"#{:02x}{:02x}{:02x}\"", rgb[0], rgb[1], rgb[2]);
+    write_config_value("page_low_color", &hex);
+    let r = clear_ui::color::srgb_to_linear(rgb[0] as f32 / 255.0);
+    let g = clear_ui::color::srgb_to_linear(rgb[1] as f32 / 255.0);
+    let b = clear_ui::color::srgb_to_linear(rgb[2] as f32 / 255.0);
+    clear_ui::color::set_page_low_color([r, g, b, 1.0]);
+}
+
+fn apply_color_borders_color(rgb: [u8; 3]) {
+    let hex = format!("\"#{:02x}{:02x}{:02x}\"", rgb[0], rgb[1], rgb[2]);
+    write_config_value("color_borders_color", &hex);
+    let r = clear_ui::color::srgb_to_linear(rgb[0] as f32 / 255.0);
+    let g = clear_ui::color::srgb_to_linear(rgb[1] as f32 / 255.0);
+    let b = clear_ui::color::srgb_to_linear(rgb[2] as f32 / 255.0);
+    clear_ui::color::set_color_borders_color([r, g, b, 1.0]);
+}
+
 pub fn view(state: &mut ColorsState, cx: f32, cy: f32, cw: f32, _ch: f32) -> PageContent {
     let mut pc = PageContent::new();
     let mut y = cy + 12.0;
 
-    // 1. Layout Section
-    let mut sec = Section::new(&mut pc, cx, y, cw, "Layout");
+    // 1. Pages Section
+    let mut sec = Section::new(&mut pc, cx, y, cw, "Pages");
     sec.spacing(8.0);
-    state.color_selectors[0].color = state.low_color;
+    state.color_selectors[0].color = state.page_low_color;
     sec.widget(&mut pc, &mut state.color_selectors[0], 12.0, 220.0, 22.0);
     sec.spacing(8.0);
+    y = sec.finish(&mut pc);
+
+    // 2. Layout Section
+    let mut sec = Section::new(&mut pc, cx, y, cw, "Layout");
+    sec.spacing(8.0);
+    state.color_selectors[7].color = state.low_color;
+    sec.widget(&mut pc, &mut state.color_selectors[7], 12.0, 220.0, 22.0);
+    sec.spacing(8.0);
     state.color_selectors[1].color = state.high_color;
     sec.widget(&mut pc, &mut state.color_selectors[1], 12.0, 220.0, 22.0);
     sec.spacing(8.0);
+    state.color_selectors[2].color = state.visual_guides_color;
+    sec.widget(&mut pc, &mut state.color_selectors[2], 12.0, 220.0, 22.0);
+    sec.spacing(8.0);
     y = sec.finish(&mut pc);
 
-    // 2. Status Section
+    // 3. Status Section
     let mut sec = Section::new(&mut pc, cx, y, cw, "Status");
     sec.spacing(8.0);
-    state.color_selectors[2].color = state.disabled_color;
-    sec.widget(&mut pc, &mut state.color_selectors[2], 12.0, 220.0, 22.0);
+    state.color_selectors[3].color = state.disabled_color;
+    sec.widget(&mut pc, &mut state.color_selectors[3], 12.0, 220.0, 22.0);
+    sec.spacing(8.0);
+    state.color_selectors[4].color = state.separator_color;
+    sec.widget(&mut pc, &mut state.color_selectors[4], 12.0, 220.0, 22.0);
     sec.spacing(8.0);
     y = sec.finish(&mut pc);
 
-    // 3. Preset Background Colors Grid
-    let mut sec = Section::new(&mut pc, cx, y, cw, "Preset Backgrounds");
-    let cols = 4;
-    let gap = 8.0;
-    let btn_w = (cw - 24.0 - (gap * (cols - 1) as f32)) / cols as f32;
-    let btn_h = 28.0;
-
-    for (i, (name, rgb)) in state.preset_colors.iter().enumerate() {
-        let col = i % cols;
-        let row = i / cols;
-        let bx = cx + 12.0 + col as f32 * (btn_w + gap);
-        let by = sec.ay() + row as f32 * (btn_h + gap);
-
-        let r = rgb[0] as f32 / 255.0;
-        let g = rgb[1] as f32 / 255.0;
-        let b = rgb[2] as f32 / 255.0;
-        let luminance = 0.299 * r + 0.587 * g + 0.114 * b;
-        let text_color = if luminance > 0.5 { [0.08, 0.08, 0.12, 1.0] } else { [0.90, 0.90, 0.95, 1.0] };
-
-        pc.button(
-            name,
-            bx,
-            by,
-            btn_w,
-            btn_h,
-            [r, g, b, 0.8],
-            [r, g, b, 1.0],
-            text_color,
-            crate::app::AppAction::Colors(ColorsMessage::SetLowColor(*rgb)),
-        );
-    }
-
-    let rows = (state.preset_colors.len() + cols - 1) / cols;
-    sec.content_y += rows as f32 * (btn_h + gap) + 4.0;
-    sec.finish(&mut pc);
+    // 4. Controls Section
+    let mut sec = Section::new(&mut pc, cx, y, cw, "Controls");
+    sec.spacing(8.0);
+    state.color_selectors[5].color = state.slider_track_color;
+    sec.widget(&mut pc, &mut state.color_selectors[5], 12.0, 220.0, 22.0);
+    sec.spacing(8.0);
+    state.color_selectors[6].color = state.color_borders_color;
+    sec.widget(&mut pc, &mut state.color_selectors[6], 12.0, 220.0, 22.0);
+    sec.spacing(8.0);
+    y = sec.finish(&mut pc);
 
     pc
 }
@@ -257,6 +320,10 @@ pub fn update(state: &mut ColorsState, msg: ColorsMessage) {
             state.low_color = rgb;
             apply_background(rgb);
         }
+        ColorsMessage::SetPageLowColor(rgb) => {
+            state.page_low_color = rgb;
+            apply_page_low_color(rgb);
+        }
         ColorsMessage::SetHighColor(rgb) => {
             state.high_color = rgb;
             apply_border_color(rgb);
@@ -265,7 +332,23 @@ pub fn update(state: &mut ColorsState, msg: ColorsMessage) {
             state.disabled_color = rgb;
             apply_disabled_color(rgb);
         }
-        ColorsMessage::PickLowColor | ColorsMessage::PickHighColor | ColorsMessage::PickDisabledColor => {}
+        ColorsMessage::SetSeparatorColor(rgb) => {
+            state.separator_color = rgb;
+            apply_separator_color(rgb);
+        }
+        ColorsMessage::SetVisualGuidesColor(rgb) => {
+            state.visual_guides_color = rgb;
+            apply_visual_guides_color(rgb);
+        }
+        ColorsMessage::SetSliderTrackColor(rgb) => {
+            state.slider_track_color = rgb;
+            apply_slider_track_color(rgb);
+        }
+        ColorsMessage::SetColorBordersColor(rgb) => {
+            state.color_borders_color = rgb;
+            apply_color_borders_color(rgb);
+        }
+        ColorsMessage::PickLowColor | ColorsMessage::PickHighColor | ColorsMessage::PickDisabledColor | ColorsMessage::PickSeparatorColor | ColorsMessage::PickVisualGuides | ColorsMessage::PickSliderTrackColor | ColorsMessage::PickPageLowColor | ColorsMessage::PickColorBordersColor => {}
         ColorsMessage::Refreshed(new) => {
             *state = new;
         }
@@ -286,10 +369,15 @@ mod tests {
 
     #[test]
     fn test_parse_color_from_key() {
-        let content = "\n[layout]\nlow_color = \"#112233\"\nhigh_color = \"#445566\"\ndisabled_color = \"#778899\"\n";
+        let content = "\n[layout]\nlow_color = \"#112233\"\nhigh_color = \"#445566\"\ndisabled_color = \"#778899\"\nstatus_separator_color = \"#aabbcc\"\nvisual_guides_color = \"#ddeeff\"\nslider_track_color = \"#123456\"\npage_low_color = \"#474751\"\ncolor_borders_color = \"#abcdef\"\n";
         assert_eq!(parse_color_from_key(content, "low_color", [0, 0, 0]), [17, 34, 51]);
         assert_eq!(parse_color_from_key(content, "high_color", [0, 0, 0]), [68, 85, 102]);
         assert_eq!(parse_color_from_key(content, "disabled_color", [0, 0, 0]), [119, 136, 153]);
+        assert_eq!(parse_color_from_key(content, "status_separator_color", [0, 0, 0]), [170, 187, 204]);
+        assert_eq!(parse_color_from_key(content, "visual_guides_color", [0, 0, 0]), [221, 238, 255]);
+        assert_eq!(parse_color_from_key(content, "slider_track_color", [0, 0, 0]), [18, 52, 86]);
+        assert_eq!(parse_color_from_key(content, "page_low_color", [0, 0, 0]), [71, 71, 81]);
+        assert_eq!(parse_color_from_key(content, "color_borders_color", [0, 0, 0]), [171, 205, 239]);
         assert_eq!(parse_color_from_key(content, "non_existent", [1, 2, 3]), [1, 2, 3]);
     }
 
@@ -316,6 +404,16 @@ mod tests {
         assert!(updated2.contains("disabled_color = \"#666666\""));
         assert!(!updated2.contains("disabled_color = \"#555555\""));
 
+        // 4. Write visual_guides_color which does not exist yet
+        assert!(write_config_value_path(path_str, "visual_guides_color", "\"#ff8c00\""));
+        let updated3 = fs::read_to_string(path_str).unwrap();
+        assert!(updated3.contains("visual_guides_color = \"#ff8c00\""));
+
+        // 5. Write slider_track_color which does not exist yet
+        assert!(write_config_value_path(path_str, "slider_track_color", "\"#123456\""));
+        let updated4 = fs::read_to_string(path_str).unwrap();
+        assert!(updated4.contains("slider_track_color = \"#123456\""));
+
         // Clean up
         let _ = fs::remove_file(path_str);
     }
diff --git a/src/pages/display.rs b/src/pages/display.rs
index 1ad3c68..804c258 100644
--- a/src/pages/display.rs
+++ b/src/pages/display.rs
@@ -83,7 +83,7 @@ pub async fn fetch_display_state() -> DisplayState {
     DisplayState {
         loaded: true,
         brightness, max_brightness, outputs, night_light,
-        brightness_spinbox: Spinbox::new(pct, 0, 100, 5).with_unit("%"),
+        brightness_spinbox: Spinbox::new(pct.max(1), 1, 100, 5).with_unit("%"),
         night_light_label: Label::new(if night_light { "Night Light: ON" } else { "Night Light: OFF" })
             .with_font_size(13.0)
             .with_color([0xd4, 0xd4, 0xd4]),
@@ -163,7 +163,7 @@ async fn is_night_light_on() -> bool {
 
 fn spawn_brightness(pct: u32) {
     let _ = tokio::process::Command::new("brightnessctl")
-        .args(["set", &format!("{}%", pct)]).spawn();
+        .args(["set", &format!("{}%", pct), "-n"]).spawn();
 }
 
 const TEXT_FG: [f32; 4] = [0.83, 0.83, 0.83, 1.0];
diff --git a/src/pages/input.rs b/src/pages/input.rs
index 2aeefb6..0a69bef 100644
--- a/src/pages/input.rs
+++ b/src/pages/input.rs
@@ -5,12 +5,12 @@ use crate::app::PageContent;
 use clear_ui::layout::Section;
 use clear_ui::widget::{Dropdown, Spinbox, Toggle, Widget, Finger, Trackpad};
 
-const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/ccec/config.toml";
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/clearwm-{}.sock", display),
-        Err(_) => "/tmp/clearwm.sock".to_string(),
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
     }
 }
 
diff --git a/src/pages/layout.rs b/src/pages/layout.rs
index a525036..0ea1459 100644
--- a/src/pages/layout.rs
+++ b/src/pages/layout.rs
@@ -5,32 +5,30 @@ use crate::app::PageContent;
 use clear_ui::layout::Section;
 use clear_ui::widget::Spinbox;
 
-const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/ccec/config.toml";
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/clearwm-{}.sock", display),
-        Err(_) => "/tmp/clearwm.sock".to_string(),
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
     }
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum WidthParam {
-    Fullscreen, Cascade, Grid, Vsplit, Hsplit, Floating,
+    Fullscreen, Cascade, Grid, Floating,
 }
 
 impl WidthParam {
-    pub const ALL: [WidthParam; 6] = [
+    pub const ALL: [WidthParam; 4] = [
         WidthParam::Fullscreen, WidthParam::Cascade, WidthParam::Grid,
-        WidthParam::Vsplit, WidthParam::Hsplit, WidthParam::Floating,
+        WidthParam::Floating,
     ];
     pub fn key(self) -> &'static str {
         match self {
             WidthParam::Fullscreen => "fullscreen_border_width",
             WidthParam::Cascade => "cascade_border_width",
             WidthParam::Grid => "grid_border_width",
-            WidthParam::Vsplit => "vsplit_border_width",
-            WidthParam::Hsplit => "hsplit_border_width",
             WidthParam::Floating => "floating_border_width",
         }
     }
@@ -39,20 +37,16 @@ impl WidthParam {
             WidthParam::Fullscreen => "Fullscreen",
             WidthParam::Cascade => "Cascade",
             WidthParam::Grid => "Grid",
-            WidthParam::Vsplit => "Vsplit",
-            WidthParam::Hsplit => "Hsplit",
             WidthParam::Floating => "Floating",
         }
     }
 }
 
-fn make_spinboxes(fs: u16, ca: u16, g: u16, v: u16, h: u16, fl: u16) -> Vec<Spinbox> {
+fn make_spinboxes(fs: u16, ca: u16, g: u16, fl: u16) -> Vec<Spinbox> {
     vec![
         Spinbox::new(fs as i32, 0, 100, 1),
         Spinbox::new(ca as i32, 0, 100, 1),
         Spinbox::new(g as i32, 0, 100, 1),
-        Spinbox::new(v as i32, 0, 100, 1),
-        Spinbox::new(h as i32, 0, 100, 1),
         Spinbox::new(fl as i32, 0, 100, 1),
     ]
 }
@@ -62,16 +56,16 @@ pub struct LayoutState {
     pub fullscreen_border_width: u16,
     pub cascade_border_width: u16,
     pub grid_border_width: u16,
-    pub vsplit_border_width: u16,
-    pub hsplit_border_width: u16,
     pub floating_border_width: u16,
     pub cascade_offset: u16,
     pub edge_gap: u16,
     pub top_gap: u16,
+    pub transition_duration: u16,
     pub spinboxes: Vec<Spinbox>,
     pub cascade_offset_spinbox: Spinbox,
     pub edge_gap_spinbox: Spinbox,
     pub top_gap_spinbox: Spinbox,
+    pub transition_duration_spinbox: Spinbox,
 }
 
 impl Default for LayoutState {
@@ -80,16 +74,16 @@ impl Default for LayoutState {
             fullscreen_border_width: 0,
             cascade_border_width: 6,
             grid_border_width: 6,
-            vsplit_border_width: 6,
-            hsplit_border_width: 6,
             floating_border_width: 6,
             cascade_offset: 20,
             edge_gap: 48,
             top_gap: 48,
-            spinboxes: make_spinboxes(0, 6, 6, 6, 6, 6),
+            transition_duration: 300,
+            spinboxes: make_spinboxes(0, 6, 6, 6),
             cascade_offset_spinbox: Spinbox::new(20, 0, 200, 1),
             edge_gap_spinbox: Spinbox::new(48, 0, 200, 1),
             top_gap_spinbox: Spinbox::new(48, 0, 200, 1),
+            transition_duration_spinbox: Spinbox::new(300, 0, 2000, 50),
         }
     }
 }
@@ -100,6 +94,7 @@ pub enum LayoutMessage {
     SetCascadeOffset(u16),
     SetEdgeGap(u16),
     SetTopGap(u16),
+    SetTransitionDuration(u16),
     Refreshed(LayoutState),
 }
 
@@ -108,26 +103,25 @@ pub fn read_layout_config() -> LayoutState {
     let fs = parse_u16_from(&content, "fullscreen_border_width", 0);
     let ca = parse_u16_from(&content, "cascade_border_width", 6);
     let g = parse_u16_from(&content, "grid_border_width", 6);
-    let v = parse_u16_from(&content, "vsplit_border_width", 6);
-    let h = parse_u16_from(&content, "hsplit_border_width", 6);
     let fl = parse_u16_from(&content, "floating_border_width", 6);
     let co = parse_u16_from(&content, "cascade_offset", 20);
     let gl = parse_u16_from(&content, "gap_left", 48);
     let gt = parse_u16_from(&content, "gap_top", 48);
+    let td = parse_u16_from(&content, "transition_duration", 300);
     LayoutState {
         fullscreen_border_width: fs,
         cascade_border_width: ca,
         grid_border_width: g,
-        vsplit_border_width: v,
-        hsplit_border_width: h,
         floating_border_width: fl,
         cascade_offset: co,
         edge_gap: gl,
         top_gap: gt,
-        spinboxes: make_spinboxes(fs, ca, g, v, h, fl),
+        transition_duration: td,
+        spinboxes: make_spinboxes(fs, ca, g, fl),
         cascade_offset_spinbox: Spinbox::new(co as i32, 0, 200, 1),
         edge_gap_spinbox: Spinbox::new(gl as i32, 0, 200, 1),
         top_gap_spinbox: Spinbox::new(gt as i32, 0, 200, 1),
+        transition_duration_spinbox: Spinbox::new(td as i32, 0, 2000, 50),
     }
 }
 
@@ -179,39 +173,50 @@ fn apply_all_widths(s: &LayoutState) {
     w("fullscreen_border_width", s.fullscreen_border_width);
     w("cascade_border_width", s.cascade_border_width);
     w("grid_border_width", s.grid_border_width);
-    w("vsplit_border_width", s.vsplit_border_width);
-    w("hsplit_border_width", s.hsplit_border_width);
     w("floating_border_width", s.floating_border_width);
     w("cascade_offset", s.cascade_offset);
     w("gap_left", s.edge_gap);
     w("gap_right", s.edge_gap);
     w("gap_bottom", s.edge_gap);
     w("gap_top", s.top_gap);
+    w("transition_duration", s.transition_duration);
 }
 
 pub fn view(state: &mut LayoutState, cx: f32, cy: f32, cw: f32, _ch: f32, sec_focused: &[bool]) -> PageContent {
     let mut pc = PageContent::new();
     let mut y = cy + 12.0;
 
+    // 1. Border Width Section
+    let mut sec_bw = Section::new(&mut pc, cx, y, cw, "Border Width");
+    sec_bw.spacing(8.0);
     for (i, param) in WidthParam::ALL.iter().enumerate() {
-        let mut sec = Section::new(&mut pc, cx, y, cw, param.label());
-        sec.spacing(8.0);
-        state.spinboxes[i].set_label("Border Width");
-        sec.widget(&mut pc, &mut state.spinboxes[i], 14.0, 200.0, 26.0);
-        if *param == WidthParam::Cascade {
-            sec.spacing(8.0);
-            state.cascade_offset_spinbox.set_label("Offset");
-            sec.widget(&mut pc, &mut state.cascade_offset_spinbox, 14.0, 200.0, 26.0);
-            sec.spacing(8.0);
-            state.edge_gap_spinbox.set_label("Edge Gap");
-            sec.widget(&mut pc, &mut state.edge_gap_spinbox, 14.0, 200.0, 26.0);
-            sec.spacing(8.0);
-            state.top_gap_spinbox.set_label("Top Gap");
-            sec.widget(&mut pc, &mut state.top_gap_spinbox, 14.0, 200.0, 26.0);
-        }
-        sec.spacing(8.0);
-        y = sec.finish_focused(&mut pc, sec_focused.get(i).copied().unwrap_or(false));
+        state.spinboxes[i].set_label(param.label());
+        sec_bw.widget(&mut pc, &mut state.spinboxes[i], 14.0, 200.0, 26.0);
+        sec_bw.spacing(8.0);
     }
+    y = sec_bw.finish_focused(&mut pc, sec_focused.get(0).copied().unwrap_or(false));
+
+    // 2. Cascade Section
+    let mut sec_cascade = Section::new(&mut pc, cx, y, cw, "Cascade");
+    sec_cascade.spacing(8.0);
+    state.cascade_offset_spinbox.set_label("Offset");
+    sec_cascade.widget(&mut pc, &mut state.cascade_offset_spinbox, 14.0, 200.0, 26.0);
+    sec_cascade.spacing(8.0);
+    state.edge_gap_spinbox.set_label("Edge Gap");
+    sec_cascade.widget(&mut pc, &mut state.edge_gap_spinbox, 14.0, 200.0, 26.0);
+    sec_cascade.spacing(8.0);
+    state.top_gap_spinbox.set_label("Top Gap");
+    sec_cascade.widget(&mut pc, &mut state.top_gap_spinbox, 14.0, 200.0, 26.0);
+    sec_cascade.spacing(8.0);
+    y = sec_cascade.finish_focused(&mut pc, sec_focused.get(1).copied().unwrap_or(false));
+
+    // 3. Movement Section
+    let mut movement_sec = Section::new(&mut pc, cx, y, cw, "Movement");
+    movement_sec.spacing(8.0);
+    state.transition_duration_spinbox.set_label("Duration (ms)");
+    movement_sec.widget(&mut pc, &mut state.transition_duration_spinbox, 14.0, 200.0, 26.0);
+    movement_sec.spacing(8.0);
+    y = movement_sec.finish_focused(&mut pc, sec_focused.get(2).copied().unwrap_or(false));
 
     pc
 }
@@ -222,8 +227,6 @@ fn set_width(state: &mut LayoutState, param: WidthParam, val: u16) {
         WidthParam::Fullscreen => state.fullscreen_border_width = val,
         WidthParam::Cascade => state.cascade_border_width = val,
         WidthParam::Grid => state.grid_border_width = val,
-        WidthParam::Vsplit => state.vsplit_border_width = val,
-        WidthParam::Hsplit => state.hsplit_border_width = val,
         WidthParam::Floating => state.floating_border_width = val,
     }
     state.spinboxes[param_idx(param)].value = val as i32;
@@ -235,9 +238,7 @@ fn param_idx(p: WidthParam) -> usize {
         WidthParam::Fullscreen => 0,
         WidthParam::Cascade => 1,
         WidthParam::Grid => 2,
-        WidthParam::Vsplit => 3,
-        WidthParam::Hsplit => 4,
-        WidthParam::Floating => 5,
+        WidthParam::Floating => 3,
     }
 }
 
@@ -262,6 +263,12 @@ pub fn update(state: &mut LayoutState, msg: LayoutMessage) {
             state.top_gap_spinbox.value = val as i32;
             apply_all_widths(state);
         }
+        LayoutMessage::SetTransitionDuration(v) => {
+            let val = v.min(2000);
+            state.transition_duration = val;
+            state.transition_duration_spinbox.value = val as i32;
+            apply_all_widths(state);
+        }
         LayoutMessage::Refreshed(new) => { *state = new; }
     }
 }
diff --git a/src/pages/notifications.rs b/src/pages/notifications.rs
index fdfe873..531d766 100644
--- a/src/pages/notifications.rs
+++ b/src/pages/notifications.rs
@@ -3,14 +3,14 @@ use std::io::Write;
 
 use crate::app::{AppAction, PageContent};
 use clear_ui::layout::Section;
-use clear_ui::widget::{Toggle, Spinbox};
+use clear_ui::widget::{Toggle, Spinbox, Slider};
 
-const CONFIG_PATH: &str = "/home/lsgalante/.config/clearwm/config.toml";
+const CONFIG_PATH: &str = "/home/lsgalante/.config/ccec/config.toml";
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/clearwm-{}.sock", display),
-        Err(_) => "/tmp/clearwm.sock".to_string(),
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
     }
 }
 
@@ -22,6 +22,8 @@ pub struct NotificationsState {
     pub bell_toggle: Toggle,
     pub duration: i32,
     pub duration_spinbox: Spinbox,
+    pub opacity: f32,
+    pub opacity_slider: Slider,
 }
 
 impl Default for NotificationsState {
@@ -35,6 +37,10 @@ impl Default for NotificationsState {
             duration_spinbox: Spinbox::new(5, 1, 60, 1)
                 .with_label("Notification Duration")
                 .with_unit("s"),
+            opacity: 0.9,
+            opacity_slider: Slider::new()
+                .with_label("Transparency")
+                .with_value(0.9),
         }
     }
 }
@@ -44,6 +50,7 @@ pub enum NotificationsMessage {
     ToggleEnable,
     ToggleBell,
     SetDuration(i32),
+    SetOpacity(f32),
     SendTestNotification,
     Refreshed(NotificationsState),
 }
@@ -53,6 +60,7 @@ pub fn read_notifications_config() -> NotificationsState {
     let enable = parse_notifications_enable(&content);
     let bell = parse_notifications_bell(&content);
     let duration = parse_notifications_duration(&content);
+    let opacity = parse_transparency_opacity(&content);
     NotificationsState {
         enable,
         enable_toggle: Toggle::new().with_label("Enable Notifications"),
@@ -62,6 +70,10 @@ pub fn read_notifications_config() -> NotificationsState {
         duration_spinbox: Spinbox::new(duration, 1, 60, 1)
             .with_label("Notification Duration")
             .with_unit("s"),
+        opacity,
+        opacity_slider: Slider::new()
+            .with_label("Transparency")
+            .with_value(opacity),
     }
 }
 
@@ -208,6 +220,94 @@ const BTN_BG: [f32; 4] = [0.20, 0.40, 0.65, 1.0];
 const BTN_HOVER: [f32; 4] = [0.28, 0.50, 0.78, 1.0];
 const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
 
+fn parse_transparency_opacity(content: &str) -> f32 {
+    let mut in_section = false;
+    for line in content.lines() {
+        let trimmed = line.trim();
+        if trimmed == "[transparency]" {
+            in_section = true;
+            continue;
+        }
+        if trimmed.starts_with('[') && in_section {
+            break;
+        }
+        if in_section && trimmed.starts_with("opacity") {
+            if let Some(val) = trimmed.split('=').nth(1) {
+                if let Ok(o) = val.trim().parse::<f32>() {
+                    return o.clamp(0.0, 1.0);
+                }
+            }
+        }
+    }
+    0.9 // default to 0.9
+}
+
+fn write_transparency_config_value(key: &str, value: &str) {
+    let content = fs::read_to_string(CONFIG_PATH).unwrap_or_default();
+    let new_line = format!("{} = {}", key, value);
+
+    let mut found = false;
+    let mut updated_lines = Vec::new();
+    let mut in_section = false;
+
+    for line in content.lines() {
+        let trimmed = line.trim();
+        if trimmed == "[transparency]" {
+            in_section = true;
+            updated_lines.push(line.to_string());
+            continue;
+        }
+        if trimmed.starts_with('[') && in_section {
+            in_section = false;
+        }
+        if in_section && trimmed.starts_with(key) {
+            found = true;
+            updated_lines.push(new_line.clone());
+        } else {
+            updated_lines.push(line.to_string());
+        }
+    }
+
+    let mut updated = updated_lines.join("\n");
+
+    if !found {
+        let mut result = String::new();
+        let has_section = content.lines().any(|l| l.trim() == "[transparency]");
+        if has_section {
+            let mut in_section = false;
+            let mut inserted = false;
+            for line in updated.lines() {
+                if line.trim() == "[transparency]" {
+                    in_section = true;
+                    result.push_str(line);
+                    result.push('\n');
+                    continue;
+                }
+                if line.trim().starts_with('[') && in_section {
+                    if !inserted {
+                        result.push_str(&new_line);
+                        result.push('\n');
+                        inserted = true;
+                    }
+                    in_section = false;
+                }
+                result.push_str(line);
+                result.push('\n');
+            }
+            if !inserted {
+                result.push_str(&new_line);
+                result.push('\n');
+            }
+            updated = result;
+        } else {
+            updated.push_str("\n[transparency]\n");
+            updated.push_str(&new_line);
+            updated.push_str("\n");
+        }
+    }
+    let _ = fs::write(CONFIG_PATH, updated);
+}
+
 pub fn view(state: &mut NotificationsState, cx: f32, cy: f32, cw: f32, _ch: f32) -> PageContent {
     let mut pc = PageContent::new();
     let y = cy + 12.0;
@@ -246,8 +346,14 @@ pub fn view(state: &mut NotificationsState, cx: f32, cy: f32, cw: f32, _ch: f32)
         );
     });
     sec.spacing(12.0);
-
     sec.finish(&mut pc);
+
+    let mut sec2 = Section::new(&mut pc, cx, sec.ay() + 24.0, cw, "Transparency");
+    state.opacity_slider.set_value(state.opacity);
+    sec2.widget(&mut pc, &mut state.opacity_slider, 14.0, 300.0, 20.0);
+    sec2.spacing(12.0);
+    sec2.finish(&mut pc);
+
     pc
 }
 
@@ -265,8 +371,13 @@ pub fn update(state: &mut NotificationsState, msg: NotificationsMessage) {
             state.duration = d;
             write_config_value("duration", &state.duration.to_string());
         }
+        NotificationsMessage::SetOpacity(o) => {
+            state.opacity = o;
+            write_transparency_config_value("opacity", &format!("{:.2}", o));
+            send_ipc_command("reload");
+        }
         NotificationsMessage::SendTestNotification => {
-            send_ipc_command("notify \"clearwm\" \"System notifications are working correctly!\"");
+            send_ipc_command("notify \"ccec\" \"System notifications are working correctly!\"");
         }
         NotificationsMessage::Refreshed(new) => {
             *state = new;
diff --git a/src/pages/status.rs b/src/pages/status.rs
index b7f6427..612f461 100644
--- a/src/pages/status.rs
+++ b/src/pages/status.rs
@@ -1,25 +1,37 @@
 use crate::app::{AppAction, PageContent};
 use clear_ui::layout::Section;
-use clear_ui::widget::{Label, Widget};
-use crate::pages::typeface::{parse_u16_from, write_config_value};
+use clear_ui::widget::{Label, Toggle, Widget, Spinbox};
+use crate::pages::typeface::parse_u16_from;
 
 #[derive(Debug, Clone)]
 pub struct StatusState {
     pub font_size: u16,
+    pub padding: u16,
+    pub separators: bool,
+    pub underline: bool,
     pub running: bool,
     pub loaded: bool,
     pub status_label: Label,
     pub size_label: Label,
+    pub separators_toggle: Toggle,
+    pub underline_toggle: Toggle,
+    pub padding_spinbox: Spinbox,
 }
 
 impl Default for StatusState {
     fn default() -> Self {
         Self {
             font_size: 11,
+            padding: 8,
+            separators: true,
+            underline: true,
             running: false,
             loaded: false,
             status_label: Label::new("Status Interface: Stopped").with_font_size(14.0).with_color([170, 51, 51]),
             size_label: Label::new("Font size: 11px").with_font_size(13.0).with_color([212, 212, 212]),
+            separators_toggle: Toggle::new().with_label("Show Separators"),
+            underline_toggle: Toggle::new().with_label("Show Underline"),
+            padding_spinbox: Spinbox::new(8, 0, 32, 1).with_label("Side Padding").with_unit("px"),
         }
     }
 }
@@ -29,7 +41,10 @@ pub enum StatusMessage {
     Refreshed(StatusState),
     FontSizeUp,
     FontSizeDown,
+    ToggleSeparators,
+    ToggleUnderline,
     ReloadStatus,
+    SetPadding(u16),
 }
 
 pub async fn fetch_status_state() -> StatusState {
@@ -39,9 +54,15 @@ pub async fn fetch_status_state() -> StatusState {
         .unwrap_or(false);
 
     let font_size = read_status_font_size().unwrap_or(11);
+    let padding = read_status_padding().unwrap_or(8);
+    let separators = read_status_separators().unwrap_or(true);
+    let underline = read_status_underline().unwrap_or(true);
     let status_color = if running { [92, 143, 97] } else { [170, 51, 51] };
     StatusState {
         font_size,
+        padding,
+        separators,
+        underline,
         running,
         loaded: true,
         status_label: Label::new(&format!("Status Interface: {}", if running { "Running" } else { "Stopped" }))
@@ -50,22 +71,111 @@ pub async fn fetch_status_state() -> StatusState {
         size_label: Label::new(&format!("Font size: {}px", font_size))
             .with_font_size(13.0)
             .with_color([212, 212, 212]),
+        separators_toggle: Toggle::new().with_label("Show Separators"),
+        underline_toggle: Toggle::new().with_label("Show Underline"),
+        padding_spinbox: Spinbox::new(padding as i32, 0, 32, 1).with_label("Side Padding").with_unit("px"),
     }
 }
 
+#[cfg(test)]
+thread_local! {
+    static TEST_CONFIG_PATH: std::cell::RefCell<Option<String>> = std::cell::RefCell::new(None);
+}
+
+fn get_config_path() -> String {
+    #[cfg(test)]
+    {
+        TEST_CONFIG_PATH.with(|p| {
+            if let Some(path) = p.borrow().as_ref() {
+                return path.clone();
+            }
+            "/home/lsgalante/.config/ccec/config.toml".to_string()
+        })
+    }
+    #[cfg(not(test))]
+    {
+        "/home/lsgalante/.config/ccec/config.toml".to_string()
+    }
+}
+
+fn write_status_value(key: &str, value: &str) {
+    crate::pages::typeface::write_config_value_path(&get_config_path(), key, value);
+}
+
 fn read_status_font_size() -> Option<u16> {
-    let content = std::fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").ok()?;
+    let content = std::fs::read_to_string(&get_config_path()).ok()?;
     Some(parse_u16_from(&content, "status_font_size", 11))
 }
 
 fn write_status_font_size(size: u16) {
-    write_config_value("status_font_size", &size.to_string());
+    write_status_value("status_font_size", &size.to_string());
+}
+
+fn read_status_padding() -> Option<u16> {
+    let content = std::fs::read_to_string(&get_config_path()).ok()?;
+    Some(parse_u16_from(&content, "status_padding", 8))
+}
+
+fn write_status_padding(padding: u16) {
+    write_status_value("status_padding", &padding.to_string());
+}
+
+fn read_status_separators() -> Option<bool> {
+    let content = std::fs::read_to_string(&get_config_path()).ok()?;
+    for line in content.lines() {
+        let trimmed = line.trim();
+        if let Some(rest) = trimmed.strip_prefix("status_separators") {
+            let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+            if let Ok(val) = rest.trim_end_matches('"').trim().parse::<bool>() {
+                return Some(val);
+            }
+        }
+    }
+    Some(true)
+}
+
+fn write_status_separators(val: bool) {
+    write_status_value("status_separators", &val.to_string());
+}
+
+fn read_status_underline() -> Option<bool> {
+    let content = std::fs::read_to_string(&get_config_path()).ok()?;
+    for line in content.lines() {
+        let trimmed = line.trim();
+        if let Some(rest) = trimmed.strip_prefix("status_underline") {
+            let rest = rest.trim_start_matches(|c: char| c == ' ' || c == '=' || c == '"');
+            if let Ok(val) = rest.trim_end_matches('"').trim().parse::<bool>() {
+                return Some(val);
+            }
+        }
+    }
+    Some(true)
+}
+
+fn write_status_underline(val: bool) {
+    write_status_value("status_underline", &val.to_string());
+}
+
+fn get_socket_path() -> String {
+    match std::env::var("WAYLAND_DISPLAY") {
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
+    }
+}
+
+fn send_ipc_command(cmd: &str) {
+    if let Ok(mut stream) = std::os::unix::net::UnixStream::connect(get_socket_path()) {
+        use std::io::Write;
+        let _ = stream.write_all(format!("{}\n", cmd).as_bytes());
+    }
 }
 
 fn status_interface_reload() {
     let _ = std::process::Command::new("pkill")
         .args(["-f", "clear-status-interface"])
-        .spawn();
+        .status();
+    std::thread::sleep(std::time::Duration::from_millis(150));
+    send_ipc_command("spawn clear-status-interface");
 }
 
 const TEXT_FG: [f32; 4] = [0.83, 0.83, 0.83, 1.0];
@@ -104,7 +214,22 @@ pub fn view(state: &mut StatusState, cx: f32, cy: f32, cw: f32, _ch: f32) -> Pag
         pc.button("+1", sec.ax(12.0 + 36.0 + 8.0), yt, 36.0, btn_h,
             BTN_ACTIVE, BTN_HOVER, WHITE,
             AppAction::Status(StatusMessage::FontSizeUp));
-        sec.content_y += btn_h + 12.0;
+        sec.content_y += btn_h + 16.0;
+
+        // Separators toggle
+        state.separators_toggle.set_toggled(state.separators);
+        sec.widget(&mut pc, &mut state.separators_toggle, 12.0, 48.0, 24.0);
+        sec.spacing(16.0);
+
+        // Underline toggle
+        state.underline_toggle.set_toggled(state.underline);
+        sec.widget(&mut pc, &mut state.underline_toggle, 12.0, 48.0, 24.0);
+        sec.spacing(16.0);
+
+        // Padding spinbox
+        state.padding_spinbox.value = state.padding as i32;
+        sec.widget(&mut pc, &mut state.padding_spinbox, 12.0, 200.0, 26.0);
+        sec.spacing(16.0);
 
         // Reload button
         let yt = sec.ay();
@@ -123,9 +248,13 @@ pub fn update(state: &mut StatusState, msg: StatusMessage) {
         StatusMessage::Refreshed(new) => {
             let was_status_hovered = state.status_label.hovered();
             let was_size_hovered = state.size_label.hovered();
+            let was_separators_hovered = state.separators_toggle.hovered();
+            let was_underline_hovered = state.underline_toggle.hovered();
             *state = new;
             state.status_label.set_hovered(was_status_hovered);
             state.size_label.set_hovered(was_size_hovered);
+            state.separators_toggle.set_hovered(was_separators_hovered);
+            state.underline_toggle.set_hovered(was_underline_hovered);
         }
         StatusMessage::FontSizeUp => {
             if state.font_size < 28 {
@@ -141,8 +270,83 @@ pub fn update(state: &mut StatusState, msg: StatusMessage) {
                 status_interface_reload();
             }
         }
+        StatusMessage::ToggleSeparators => {
+            state.separators = !state.separators;
+            write_status_separators(state.separators);
+            status_interface_reload();
+        }
+        StatusMessage::ToggleUnderline => {
+            state.underline = !state.underline;
+            write_status_underline(state.underline);
+            status_interface_reload();
+        }
+        StatusMessage::SetPadding(val) => {
+            state.padding = val;
+            write_status_padding(val);
+            status_interface_reload();
+        }
         StatusMessage::ReloadStatus => {
             status_interface_reload();
         }
     }
 }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use std::fs;
+
+    #[test]
+    fn test_read_write_separators() {
+        let dir = std::env::temp_dir();
+        let path = dir.join("test_status_separators.toml");
+        let path_str = path.to_str().unwrap().to_string();
+
+        let _ = fs::write(&path_str, "[layout]\nstatus_separators = true\nstatus_padding = 8\n");
+        TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = Some(path_str));
+
+        let original = read_status_separators().unwrap_or(true);
+        write_status_separators(!original);
+        assert_eq!(read_status_separators(), Some(!original));
+        write_status_separators(original);
+        assert_eq!(read_status_separators(), Some(original));
+
+        let _ = fs::remove_file(path);
+    }
+
+    #[test]
+    fn test_read_write_padding() {
+        let dir = std::env::temp_dir();
+        let path = dir.join("test_status_padding.toml");
+        let path_str = path.to_str().unwrap().to_string();
+
+        let _ = fs::write(&path_str, "[layout]\nstatus_separators = true\nstatus_padding = 8\n");
+        TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = Some(path_str));
+
+        let original = read_status_padding().unwrap_or(8);
+        write_status_padding(12);
+        assert_eq!(read_status_padding(), Some(12));
+        write_status_padding(original);
+        assert_eq!(read_status_padding(), Some(original));
+
+        let _ = fs::remove_file(path);
+    }
+
+    #[test]
+    fn test_read_write_underline() {
+        let dir = std::env::temp_dir();
+        let path = dir.join("test_status_underline.toml");
+        let path_str = path.to_str().unwrap().to_string();
+
+        let _ = fs::write(&path_str, "[layout]\nstatus_underline = true\nstatus_padding = 8\n");
+        TEST_CONFIG_PATH.with(|p| *p.borrow_mut() = Some(path_str));
+
+        let original = read_status_underline().unwrap_or(true);
+        write_status_underline(!original);
+        assert_eq!(read_status_underline(), Some(!original));
+        write_status_underline(original);
+        assert_eq!(read_status_underline(), Some(original));
+
+        let _ = fs::remove_file(path);
+    }
+}
diff --git a/src/pages/typeface.rs b/src/pages/typeface.rs
index 2bab21d..9e799f0 100644
--- a/src/pages/typeface.rs
+++ b/src/pages/typeface.rs
@@ -253,7 +253,11 @@ pub fn parse_u16_from(content: &str, key: &str, default: u16) -> u16 {
 }
 
 pub fn write_config_value(key: &str, value: &str) -> bool {
-    let content = fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").unwrap_or_default();
+    write_config_value_path("/home/lsgalante/.config/ccec/config.toml", key, value)
+}
+
+pub fn write_config_value_path(path: &str, key: &str, value: &str) -> bool {
+    let content = fs::read_to_string(path).unwrap_or_default();
     let new_line = format!("{} = {}", key, value);
     let mut found = false;
     let updated: String = content.lines()
@@ -274,14 +278,14 @@ pub fn write_config_value(key: &str, value: &str) -> bool {
             result.push_str(line); result.push('\n');
         }
         if in_layout && !inserted { result.push_str(&new_line); result.push('\n'); }
-        fs::write("/home/lsgalante/.config/clearwm/config.toml", result).is_ok()
-    } else { fs::write("/home/lsgalante/.config/clearwm/config.toml", updated).is_ok() }
+        fs::write(path, result).is_ok()
+    } else { fs::write(path, updated).is_ok() }
 }
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/clearwm-{}.sock", display),
-        Err(_) => "/tmp/clearwm.sock".to_string(),
+        Ok(display) => format!("/tmp/ccec-{}.sock", display),
+        Err(_) => "/tmp/ccec.sock".to_string(),
     }
 }
 
@@ -293,12 +297,12 @@ fn send_ipc_command(cmd: &str) {
 }
 
 fn read_border_font_size() -> Option<u16> {
-    let content = fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").ok()?;
+    let content = fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
     Some(parse_u16_from(&content, "border_font_size", 11))
 }
 
 fn read_status_size() -> Option<u16> {
-    let content = fs::read_to_string("/home/lsgalante/.config/clearwm/config.toml").ok()?;
+    let content = fs::read_to_string("/home/lsgalante/.config/ccec/config.toml").ok()?;
     Some(parse_u16_from(&content, "status_font_size", 11))
 }