diff --git a/app/dts/behaviors/backlight.dtsi b/app/dts/behaviors/backlight.dtsi
index b05d97ae..6127f605 100644
--- a/app/dts/behaviors/backlight.dtsi
+++ b/app/dts/behaviors/backlight.dtsi
@@ -9,7 +9,7 @@
 		/omit-if-no-ref/ bl: behavior_backlight {
 			compatible = "zmk,behavior-backlight";
 			label = "BACKLIGHT";
-			#binding-cells = <1>;
+			#binding-cells = <2>;
 		};
 	};
 };
diff --git a/app/dts/bindings/behaviors/zmk,behavior-backlight.yaml b/app/dts/bindings/behaviors/zmk,behavior-backlight.yaml
index e035e15e..159a7c70 100644
--- a/app/dts/bindings/behaviors/zmk,behavior-backlight.yaml
+++ b/app/dts/bindings/behaviors/zmk,behavior-backlight.yaml
@@ -5,4 +5,4 @@ description: Backlight behavior
 
 compatible: "zmk,behavior-backlight"
 
-include: one_param.yaml
+include: two_param.yaml
diff --git a/app/include/dt-bindings/zmk/backlight.h b/app/include/dt-bindings/zmk/backlight.h
index c33e4344..70572437 100644
--- a/app/include/dt-bindings/zmk/backlight.h
+++ b/app/include/dt-bindings/zmk/backlight.h
@@ -4,8 +4,16 @@
  * SPDX-License-Identifier: MIT
  */
 
-#define BL_TOG 0
-#define BL_ON 1
-#define BL_OFF 2
-#define BL_INC 3
-#define BL_DEC 4
+#define BL_TOG_CMD 0
+#define BL_ON_CMD 1
+#define BL_OFF_CMD 2
+#define BL_INC_CMD 3
+#define BL_DEC_CMD 4
+#define BL_SET_CMD 5
+
+#define BL_TOG BL_TOG_CMD 0
+#define BL_ON BL_ON_CMD 0
+#define BL_OFF BL_OFF_CMD 0
+#define BL_INC BL_INC_CMD 0
+#define BL_DEC BL_DEC_CMD 0
+#define BL_SET BL_SET_CMD
diff --git a/app/include/zmk/backlight.h b/app/include/zmk/backlight.h
index 817efe7a..8711d884 100644
--- a/app/include/zmk/backlight.h
+++ b/app/include/zmk/backlight.h
@@ -6,14 +6,11 @@
 
 #pragma once
 
-int zmk_backlight_set_on(bool on);
-bool zmk_backlight_is_on();
-
-int zmk_backlight_set_brt(int brt);
-int zmk_backlight_get_brt();
-
 int zmk_backlight_toggle();
+bool zmk_backlight_get_on();
 int zmk_backlight_on();
 int zmk_backlight_off();
-int zmk_backlight_inc();
-int zmk_backlight_dec();
+uint8_t zmk_backlight_calc_brt(int direction);
+int zmk_backlight_set_brt(uint8_t brightness);
+int zmk_backlight_adjust_brt(int direction);
+int zmk_backlight_get_brt();
diff --git a/app/src/backlight.c b/app/src/backlight.c
index 517e6133..fc8831c7 100644
--- a/app/src/backlight.c
+++ b/app/src/backlight.c
@@ -32,6 +32,8 @@ static const struct device *const backlight_dev = DEVICE_DT_GET(DT_CHOSEN(zmk_ba
 
 #define BACKLIGHT_NUM_LEDS (DT_NUM_CHILD(DT_CHOSEN(zmk_backlight)))
 
+#define BRT_MAX 100
+
 struct backlight_state {
     uint8_t brightness;
     bool on;
@@ -80,16 +82,7 @@ static void zmk_backlight_save_state_work() {
 }
 
 static struct k_delayed_work backlight_save_work;
-#endif // IS_ENABLED(CONFIG_SETTINGS)
-
-static int zmk_backlight_save_state() {
-#if IS_ENABLED(CONFIG_SETTINGS)
-    k_delayed_work_cancel(&backlight_save_work);
-    return k_delayed_work_submit(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
-#else
-    return 0;
 #endif
-}
 
 static int zmk_backlight_init(const struct device *_arg) {
     if (!device_is_ready(backlight_dev)) {
@@ -114,11 +107,22 @@ static int zmk_backlight_init(const struct device *_arg) {
     return zmk_backlight_update();
 }
 
-int zmk_backlight_set_on(bool on) {
+static int zmk_backlight_save_state() {
+#if IS_ENABLED(CONFIG_SETTINGS)
+    k_delayed_work_cancel(&backlight_save_work);
+    return k_delayed_work_submit(&backlight_save_work, K_MSEC(CONFIG_ZMK_SETTINGS_SAVE_DEBOUNCE));
+#else
+    return 0;
+#endif
+}
+
+bool zmk_backlight_get_on() { return state.on; }
+
+int zmk_backlight_on() {
     if (!state.on && state.brightness == 0) {
         state.brightness = CONFIG_ZMK_BACKLIGHT_BRT_STEP;
     }
-    state.on = on;
+    state.on = true;
 
     int rc = zmk_backlight_update();
     if (rc != 0) {
@@ -128,11 +132,9 @@ int zmk_backlight_set_on(bool on) {
     return zmk_backlight_save_state();
 }
 
-bool zmk_backlight_is_on() { return state.on; }
+int zmk_backlight_off() {
 
-int zmk_backlight_set_brt(int brt) {
-    state.on = (brt > 0);
-    state.brightness = CLAMP(brt, 0, 100);
+    state.on = false;
 
     int rc = zmk_backlight_update();
     if (rc != 0) {
@@ -144,21 +146,42 @@ int zmk_backlight_set_brt(int brt) {
 
 int zmk_backlight_get_brt() { return state.on ? state.brightness : 0; }
 
-int zmk_backlight_toggle() { return zmk_backlight_set_on(!state.on); }
+int zmk_backlight_toggle() { return state.on ? zmk_backlight_off() : zmk_backlight_on(); }
 
-int zmk_backlight_on() { return zmk_backlight_set_on(true); }
-
-int zmk_backlight_off() { return zmk_backlight_set_on(false); }
-
-int zmk_backlight_inc() {
-    if (!state.on) {
-        return zmk_backlight_set_brt(MAX(state.brightness, CONFIG_ZMK_BACKLIGHT_BRT_STEP));
+int zmk_backlight_set_brt(uint8_t brightness) {
+    if (brightness > BRT_MAX) {
+        brightness = BRT_MAX;
     }
-    return zmk_backlight_set_brt(state.brightness + CONFIG_ZMK_BACKLIGHT_BRT_STEP);
+
+    state.brightness = brightness;
+    state.on = (brightness > 0);
+
+    int rc = zmk_backlight_update();
+    if (rc != 0) {
+        return rc;
+    }
+
+    return zmk_backlight_save_state();
 }
 
-int zmk_backlight_dec() {
-    return zmk_backlight_set_brt(state.brightness - CONFIG_ZMK_BACKLIGHT_BRT_STEP);
+uint8_t zmk_backlight_calc_brt(int direction) {
+    uint8_t brightness = state.brightness;
+
+    int b = state.brightness + (direction * CONFIG_ZMK_BACKLIGHT_BRT_STEP);
+    return CLAMP(b, 0, BRT_MAX);
+}
+
+int zmk_backlight_adjust_brt(int direction) {
+
+    state.brightness = zmk_backlight_calc_brt(direction);
+    state.on = (state.brightness > 0);
+
+    int rc = zmk_backlight_update();
+    if (rc != 0) {
+        return rc;
+    }
+
+    return zmk_backlight_save_state();
 }
 
 #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE)
@@ -170,39 +193,34 @@ static bool auto_off_usb_prev_state = false;
 #endif
 
 #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE) || IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
+static int backlight_auto_state(bool *prev_state, bool *new_state) {
+    if (state.on == *new_state) {
+        return 0;
+    }
+    if (*new_state) {
+        state.on = *prev_state;
+        *prev_state = false;
+        return zmk_backlight_on();
+    } else {
+        state.on = false;
+        *prev_state = true;
+        return zmk_backlight_off();
+    }
+}
+
 static int backlight_event_listener(const zmk_event_t *eh) {
 
 #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_IDLE)
     if (as_zmk_activity_state_changed(eh)) {
         bool new_state = (zmk_activity_get_state() == ZMK_ACTIVITY_ACTIVE);
-        if (state.on == new_state) {
-            return 0;
-        }
-        if (new_state) {
-            state.on = auto_off_idle_prev_state;
-            auto_off_idle_prev_state = false;
-        } else {
-            state.on = false;
-            auto_off_idle_prev_state = true;
-        }
-        return zmk_backlight_update();
+        return backlight_auto_state(&auto_off_idle_prev_state, &new_state);
     }
 #endif
 
 #if IS_ENABLED(CONFIG_ZMK_BACKLIGHT_AUTO_OFF_USB)
     if (as_zmk_usb_conn_state_changed(eh)) {
         bool new_state = zmk_usb_is_powered();
-        if (state.on == new_state) {
-            return 0;
-        }
-        if (new_state) {
-            state.on = auto_off_usb_prev_state;
-            auto_off_usb_prev_state = false;
-        } else {
-            state.on = false;
-            auto_off_usb_prev_state = true;
-        }
-        return zmk_backlight_update();
+        return backlight_auto_state(&auto_off_usb_prev_state, &new_state);
     }
 #endif
 
diff --git a/app/src/behaviors/behavior_backlight.c b/app/src/behaviors/behavior_backlight.c
index 8d921f45..3dcbd3c4 100644
--- a/app/src/behaviors/behavior_backlight.c
+++ b/app/src/behaviors/behavior_backlight.c
@@ -20,21 +20,52 @@ LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
 
 static int behavior_backlight_init(const struct device *dev) { return 0; }
 
+static int
+on_keymap_binding_convert_central_state_dependent_params(struct zmk_behavior_binding *binding,
+                                                         struct zmk_behavior_binding_event event) {
+    switch (binding->param1) {
+    case BL_TOG_CMD: {
+        binding->param1 = zmk_backlight_get_on() ? BL_OFF_CMD : BL_ON_CMD;
+        break;
+    }
+    case BL_INC_CMD: {
+        uint8_t brightness = zmk_backlight_calc_brt(1);
+
+        binding->param1 = BL_SET_CMD;
+        binding->param2 = brightness;
+        break;
+    }
+    case BL_DEC_CMD: {
+        uint8_t brightness = zmk_backlight_calc_brt(-1);
+
+        binding->param1 = BL_SET_CMD;
+        binding->param2 = brightness;
+        break;
+    }
+    default:
+        return 0;
+    }
+
+    LOG_DBG("Backlight relative to absolute (%d/%d)", binding->param1, binding->param2);
+
+    return 0;
+}
+
 static int on_keymap_binding_pressed(struct zmk_behavior_binding *binding,
                                      struct zmk_behavior_binding_event event) {
     switch (binding->param1) {
-    case BL_TOG:
+    case BL_TOG_CMD:
         return zmk_backlight_toggle();
-    case BL_ON:
+    case BL_ON_CMD:
         return zmk_backlight_on();
-    case BL_OFF:
+    case BL_OFF_CMD:
         return zmk_backlight_off();
-    case BL_INC:
-        return zmk_backlight_inc();
-    case BL_DEC:
-        return zmk_backlight_dec();
-    default:
-        LOG_ERR("Unknown backlight command: %d", binding->param1);
+    case BL_INC_CMD:
+        return zmk_backlight_adjust_brt(1);
+    case BL_DEC_CMD:
+        return zmk_backlight_adjust_brt(-1);
+    case BL_SET_CMD:
+        return zmk_backlight_set_brt(binding->param2);
     }
 
     return -ENOTSUP;
@@ -46,6 +77,8 @@ static int on_keymap_binding_released(struct zmk_behavior_binding *binding,
 }
 
 static const struct behavior_driver_api behavior_backlight_driver_api = {
+    .binding_convert_central_state_dependent_params =
+        on_keymap_binding_convert_central_state_dependent_params,
     .binding_pressed = on_keymap_binding_pressed,
     .binding_released = on_keymap_binding_released,
 };