Commit 6a4d3c6f2b48

Vincent Demeester <vincent@sbr.pm>
2025-11-21 23:24:42
feat(keyboards): Add key repeat to eyelash_corne and implement alternate repeak
- Replace MUTE with key repeat on Bepo, ErgoL, and Qwerty layers - Enable repeating last keypress for faster text editing - Add keymap-drawer mappings for REPEAT visualization Added custom alternate repeat behavior to eyelash_corne keyboard: - Created alt-repeat.dtsi with mod-morph behavior (DOT/COMMA toggle) - Included helper macros for common character pairs - Integrated alternate repeat alongside key repeat on all main layers - Added visualization support in keymap-drawer config The alternate repeat key is positioned next to the standard repeat key, providing context-aware complementary character input. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 7d2f360
Changed files (4)
keyboards/eyelash_corne/config/alt-repeat.dtsi
@@ -0,0 +1,530 @@
+/*
+ * Alternate Repeat - Similar to QMK's QK_AREP
+ *
+ * This implementation provides alternate repeat functionality inspired by QMK.
+ * It includes default alternate key pairs for navigation, brackets, media keys,
+ * and common programming shortcuts.
+ *
+ * Default Alternate Pairs (from QMK):
+ * Navigation:
+ * - Left ↔ Right Arrow
+ * - Up ↔ Down Arrow
+ * - Home ↔ End
+ * - Page Up ↔ Page Down
+ *
+ * Brackets:
+ * - [ ↔ ]
+ * - { ↔ }
+ * - ( ↔ )
+ * - < ↔ >
+ *
+ * Misc:
+ * - Backspace ↔ Delete
+ * - , ↔ .
+ * - ; ↔ :
+ * - / ↔ \
+ *
+ * Media:
+ * - Volume Up ↔ Volume Down
+ * - Brightness Up ↔ Brightness Down
+ * - Next Track ↔ Previous Track
+ *
+ * Programming:
+ * - Forward ↔ Backward
+ * - Next ↔ Previous
+ *
+ * Note: Due to ZMK's devicetree-based architecture, this implementation uses
+ * a combination of behaviors and macros. For full context-aware alternates
+ * like QMK's get_alt_repeat_key_keycode_user(), custom C code would be needed.
+ */
+
+/ {
+    behaviors {
+        /*
+         * Main alternate repeat behavior
+         * This is a basic implementation that handles common punctuation pairs.
+         * For directional keys and more complex alternates, use dedicated macros.
+         */
+        alt_repeat: alt_repeat {
+            compatible = "zmk,behavior-mod-morph";
+            label = "ALT_REPEAT";
+            #binding-cells = <0>;
+            bindings = <&kp DOT>, <&kp COMMA>;  // Default: . ↔ ,
+            mods = <(MOD_LSFT|MOD_RSFT)>;
+        };
+    };
+
+    macros {
+        /*
+         * Navigation Alternates
+         */
+
+        // Left ↔ Right Arrow
+        alt_left: alt_left {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_LEFT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp RIGHT>;
+        };
+
+        alt_right: alt_right {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_RIGHT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp LEFT>;
+        };
+
+        // Up ↔ Down Arrow
+        alt_up: alt_up {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_UP";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp DOWN>;
+        };
+
+        alt_down: alt_down {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_DOWN";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp UP>;
+        };
+
+        // Home ↔ End
+        alt_home: alt_home {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_HOME";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp END>;
+        };
+
+        alt_end: alt_end {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_END";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp HOME>;
+        };
+
+        // Page Up ↔ Page Down
+        alt_pgup: alt_pgup {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_PGUP";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp PG_DN>;
+        };
+
+        alt_pgdn: alt_pgdn {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_PGDN";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp PG_UP>;
+        };
+
+        /*
+         * Bracket Alternates
+         */
+
+        // [ ↔ ]
+        alt_lbkt: alt_lbkt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_LBKT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp RBKT>;
+        };
+
+        alt_rbkt: alt_rbkt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_RBKT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp LBKT>;
+        };
+
+        // { ↔ }
+        alt_lbrc: alt_lbrc {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_LBRC";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp RBRC>;
+        };
+
+        alt_rbrc: alt_rbrc {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_RBRC";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp LBRC>;
+        };
+
+        // ( ↔ )
+        alt_lpar: alt_lpar {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_LPAR";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp RPAR>;
+        };
+
+        alt_rpar: alt_rpar {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_RPAR";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp LPAR>;
+        };
+
+        // < ↔ >
+        alt_lt: alt_lt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_LT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp GT>;
+        };
+
+        alt_gt: alt_gt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_GT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp LT>;
+        };
+
+        /*
+         * Misc Alternates
+         */
+
+        // Backspace ↔ Delete
+        alt_bspc: alt_bspc {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_BSPC";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp DEL>;
+        };
+
+        alt_del: alt_del {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_DEL";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp BSPC>;
+        };
+
+        // , ↔ .
+        alt_comma: alt_comma {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_COMMA";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp DOT>;
+        };
+
+        alt_dot: alt_dot {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_DOT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp COMMA>;
+        };
+
+        // ; ↔ :
+        alt_semi: alt_semi {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_SEMI";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp COLON>;
+        };
+
+        alt_colon: alt_colon {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_COLON";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp SEMI>;
+        };
+
+        // / ↔ \
+        alt_fslh: alt_fslh {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_FSLH";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp BSLH>;
+        };
+
+        alt_bslh: alt_bslh {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_BSLH";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp FSLH>;
+        };
+
+        // " ↔ '
+        alt_dqt: alt_dqt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_DQT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp SQT>;
+        };
+
+        alt_sqt: alt_sqt {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_SQT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp DQT>;
+        };
+
+        /*
+         * Media Key Alternates
+         */
+
+        // Volume Up ↔ Volume Down
+        alt_volu: alt_volu {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_VOLU";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_VOL_DN>;
+        };
+
+        alt_vold: alt_vold {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_VOLD";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_VOL_UP>;
+        };
+
+        // Brightness Up ↔ Brightness Down
+        alt_briu: alt_briu {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_BRIU";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_BRI_DN>;
+        };
+
+        alt_brid: alt_brid {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_BRID";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_BRI_UP>;
+        };
+
+        // Next Track ↔ Previous Track
+        alt_next: alt_next {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_NEXT";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_PREV>;
+        };
+
+        alt_prev: alt_prev {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_PREV";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp C_NEXT>;
+        };
+
+        /*
+         * Programming Shortcuts
+         * Note: In QMK these work with modifiers (e.g., Ctrl+F ↔ Ctrl+B)
+         * In ZMK, you would bind these with modifiers in your keymap
+         */
+
+        // Forward ↔ Backward (F ↔ B)
+        alt_f: alt_f {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_F";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp B>;
+        };
+
+        alt_b: alt_b {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_B";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp F>;
+        };
+
+        // Down ↔ Up (D ↔ U)
+        alt_d: alt_d {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_D";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp U>;
+        };
+
+        alt_u: alt_u {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_U";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp D>;
+        };
+
+        // Next ↔ Previous (N ↔ P)
+        alt_n: alt_n {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_N";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp P>;
+        };
+
+        alt_p: alt_p {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_P";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp N>;
+        };
+
+        // Home ↔ End (A ↔ E)
+        alt_a: alt_a {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_A";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp E>;
+        };
+
+        alt_e: alt_e {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_E";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp A>;
+        };
+
+        // Vim jump list: Older ↔ Newer (O ↔ I)
+        alt_o: alt_o {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_O";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp I>;
+        };
+
+        alt_i: alt_i {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_I";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp O>;
+        };
+
+        // Vim: Down ↔ Up (J ↔ K)
+        alt_j: alt_j {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_J";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp K>;
+        };
+
+        alt_k: alt_k {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_K";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp J>;
+        };
+
+        // Vim: Left ↔ Right (H ↔ L)
+        alt_h: alt_h {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_H";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp L>;
+        };
+
+        alt_l: alt_l {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_L";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp H>;
+        };
+
+        // Vim: Forward ↔ Backward by word (W ↔ B)
+        alt_w: alt_w {
+            compatible = "zmk,behavior-macro";
+            label = "ALT_W";
+            #binding-cells = <0>;
+            wait-ms = <0>;
+            tap-ms = <0>;
+            bindings = <&kp B>;
+        };
+
+        // Note: alt_b is already defined above for F ↔ B pair
+        // For W ↔ B, you can use alt_w for W→B and alt_b for B→W
+    };
+};
keyboards/eyelash_corne/config/eyelash_corne.keymap
@@ -19,6 +19,7 @@
 #include "hold-tap.dtsi"
 #include "mod-morph.dtsi"
 #include "mouse.dtsi"
+#include "alt-repeat.dtsi"
 
 #define ZMK_MOUSE_DEFAULT_MOVE_VAL 1200  // 600
 #define ZMK_MOUSE_DEFAULT_SCRL_VAL 20    // 10
@@ -36,9 +37,9 @@ ZMK_LAYER(Bepo,
 // ╭───────────┬───────────┬───────────┬───────────┬────────────┬────────────╮                                ╭───────────┬─────────────┬─────────────┬────────────┬────────────┬────────────╮
      &kp TAB     &b_pipe     &kp EACUT   &p_amp      &kp O        &AGRA E                 &kp UP                &car_excl   &kp V         &kp D         &kp L        &kp J        &kp Z
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &smart_num NUM NUM   &hml GL A   &hml AL U   &hml SL I   &cl_e_euro   &hyp_com_smc  &kp LEFT  &kp RET  &kp RIGHT    &hmr HL C   &hmr CR T     &hmr SR S     &hmr AR R    &hmr GL N    &kp M
+     &smart_num NUM NUM   &hml GL A   &hml AL U   &hml SL I   &cl_e_euro   &hyp_com_smc  &kp LEFT  &alt_repeat  &kp RIGHT    &hmr HL C   &hmr CR T     &hmr SR S     &hmr AR R    &hmr GL N    &kp M
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &kp GRAVE   &AGRA A     &kp Y       &kp X       &dot_col     &kp K        &kp C_MUTE &kp DOWN              &sqt_qma    &kp Q         &kp G         &kp H        &kp F        &kp W
+     &kp GRAVE   &AGRA A     &kp Y       &kp X       &dot_col     &kp K        &key_repeat &kp DOWN          &sqt_qma    &kp Q         &kp G         &kp H        &kp F        &kp W
 // ╰───────────┴───────────────────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┴────────────┴────────────╯
                                         &lt ACC DEL  &num_spc_und &lt NAV BSPC                                   &kp SL      &lt SYM RET   &kp AR
 //                                     ╰───────────┴────────────┴────────────╯                                ╰───────────┴─────────────┴─────────────╯
@@ -51,9 +52,9 @@ ZMK_LAYER(ErgoL,
 // ╭───────────┬───────────┬───────────┬───────────┬────────────┬────────────╮                                ╭───────────┬─────────────┬─────────────┬────────────┬────────────┬────────────╮
      &kp TAB     &kp Q       &kp C       &kp O       &kp P        &kp  W                  &kp UP                &kp J       &kp M         &kp D         &kp EXCL     &kp Y        &kp LBKT
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &kp EQUAL   &hml GL A   &hml AL S   &hml SL E   &hml CL N    &kp F         &kp LEFT  &kp RET  &kp RIGHT    &kp L       &hmr CR R     &hmr SR T     &hmr AR I    &hmr GL U    &kp SQT
+     &kp EQUAL   &hml GL A   &hml AL S   &hml SL E   &hml CL N    &kp F         &kp LEFT  &alt_repeat  &kp RIGHT    &kp L       &hmr CR R     &hmr SR T     &hmr AR I    &hmr GL U    &kp SQT
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &kp GRAVE   &kp Z       &kp X       &min_qma    &kp V        &kp B        &kp C_MUTE &kp DOWN              &dot_col    &kp H         &kp G         &com_smc     &kp K        &kp RBKT
+     &kp GRAVE   &kp Z       &kp X       &min_qma    &kp V        &kp B        &key_repeat &kp DOWN          &dot_col    &kp H         &kp G         &com_smc     &kp K        &kp RBKT
 // ╰───────────┴───────────────────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┴────────────┴────────────╯
                                          ___         ___          ___                                           ___         ___           ___
 //                                     ╰───────────┴────────────┴────────────╯                                ╰───────────┴─────────────┴─────────────╯
@@ -65,9 +66,9 @@ ZMK_LAYER(Qwerty,
 // ╭───────────┬───────────┬───────────┬───────────┬────────────┬────────────╮                                ╭───────────┬─────────────┬─────────────┬────────────┬────────────┬────────────╮
      &kp TAB     &kp Q       &kp W       &kp E       &kp R        &kp T                   &kp UP                &kp Y       &kp U         &kp I         &kp O        &kp P        &kp LBKT
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &kp EQUAL   &hml GL A   &hml AL S   &hml SL D   &hml CL F    &kp G         &kp LEFT  &kp RET  &kp RIGHT    &kp H       &hmr CR J     &hmr SR K     &hmr AR L   &hmr GL SEMI  &kp SQT
+     &kp EQUAL   &hml GL A   &hml AL S   &hml SL D   &hml CL F    &kp G         &kp LEFT  &alt_repeat  &kp RIGHT    &kp H       &hmr CR J     &hmr SR K     &hmr AR L   &hmr GL SEMI  &kp SQT
 // ├───────────┼───────────┼───────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┼────────────┼────────────┤
-     &kp GRAVE   &kp Z       &kp X       &kp C       &kp V        &kp B        &kp C_MUTE &kp DOWN              &kp N       &kp M         &kp COMMA     &kp DOT      &kp FSLH     &kp RBKT
+     &kp GRAVE   &kp Z       &kp X       &kp C       &kp V        &kp B        &key_repeat &kp DOWN          &kp N       &kp M         &kp COMMA     &kp DOT      &kp FSLH     &kp RBKT
 // ╰───────────┴───────────────────────┼───────────┼────────────┼────────────┤                                ├───────────┼─────────────┼─────────────┼────────────┴────────────┴────────────╯
                                          ___         ___          ___                                           ___         ___           ___
 //                                     ╰───────────┴────────────┴────────────╯                                ╰───────────┴─────────────┴─────────────╯
keyboards/keymap-drawer/config.yaml
@@ -57,8 +57,8 @@ draw_config:
 
     /* color accent for combo boxes */
     rect.combo, rect.combo-separate {
-        fill: #666;
-        stroke: #aaa;
+        fill: #4a5568;
+        stroke: #cbd5e0;
         stroke-width: 2;
     }
 
@@ -119,7 +119,8 @@ draw_config:
 
     /* styling for unused/empty keys (XXXXXXX, KC_NO) */
     /* Target keys that have neither text nor glyph (use) elements */
-    g.key:not(:has(text)):not(:has(use)) rect.key {
+    /* Exclude combo diagram keys */
+    g[class*='layer-']:not([class*='combopos']) g.key:not(:has(text)):not(:has(use)) rect.key {
         fill: #0d1117;
         stroke: #30363d;
         stroke-dasharray: 2, 2;
@@ -279,6 +280,11 @@ draw_config:
         stroke: white;
         stroke-width: 4px;
     }
+
+    .layer-lock {
+        transform: scale(1.8);
+        transform-box: fill-box;
+    }
   svg_extra_style: ''
   shrink_wide_legends: 6
   glyph_tap_size: 14
@@ -387,6 +393,11 @@ draw_config:
           <path fill="#fff" stroke="none" d="M11.02 4v16a1 1 0 0 0 1.52.85l13-8a1 1 0 0 0 0-1.7l-13-8a1 1 0 0 0-1.52.85Z" style="fill:#fff;fill-opacity:1"/>
           <path fill="#fff" stroke="none" d="M1.6 3h2.72c.82 0 1.48.65 1.48 1.45V19.5c0 .8-.66 1.44-1.48 1.44h-2.7c-.82 0-1.48-.65-1.48-1.44V4.45C.14 3.65.8 3 1.61 3Z" style="fill:#fff;fill-opacity:1;stroke:none;stroke-width:0;stroke-dasharray:none"/>
       </svg>
+    layer-lock: |
+      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+          <rect x="3" y="11" width="18" height="11" rx="2" ry="2" fill="#fff"/>
+          <path d="M7 11V7a5 5 0 0 1 10 0v4" stroke="#fff" fill="none"/>
+      </svg>
   glyph_urls:
     tabler: https://unpkg.com/@tabler/icons/icons/outline/{}.svg
     mdi: https://raw.githubusercontent.com/Templarian/MaterialDesign-SVG/master/svg/{}.svg
@@ -552,6 +563,8 @@ parse_config:
     "&AIGU SPACE": "'"
     "&kp AE": "Æ"
     "&kp OE": "Œ"
+    "&key_repeat": "REPEAT"
+    "&alt_repeat": "ALT_REP"
   sticky_label: sticky
   toggle_label: toggle
   trans_legend:
@@ -652,6 +665,7 @@ parse_config:
     BT_CLR: '$$bt-clear$$'
     BT_NXT: '$$bt-next$$'
     BT_PRV: '$$bt-prev$$'
+    '&key_repeat': 'REPEAT'
     # QMK/Moonlander specific keycodes
     FR_DQUO: '"'
     FR_QUOT: "'"
keyboards/eyelash_corne.svg
@@ -280,8 +280,8 @@ rect.side {
 
 /* color accent for combo boxes */
 rect.combo, rect.combo-separate {
-    fill: #666;
-    stroke: #aaa;
+    fill: #4a5568;
+    stroke: #cbd5e0;
     stroke-width: 2;
 }
 
@@ -340,6 +340,16 @@ text.trans {
     fill: #7b7e81;
 }
 
+/* styling for unused/empty keys (XXXXXXX, KC_NO) */
+/* Target keys that have neither text nor glyph (use) elements */
+/* Exclude combo diagram keys */
+g[class*='layer-']:not([class*='combopos']) g.key:not(:has(text)):not(:has(use)) rect.key {
+    fill: #0d1117;
+    stroke: #30363d;
+    stroke-dasharray: 2, 2;
+    opacity: 0.5;
+}
+
 /* styling for combo dendrons */
 path.combo {
     stroke-width: 1;
@@ -493,6 +503,11 @@ path.combo {
     stroke: white;
     stroke-width: 4px;
 }
+
+.layer-lock {
+    transform: scale(1.8);
+    transform-box: fill-box;
+}
 </style>
 <g transform="translate(30, 0)" class="layer-Bepo">
 <text x="0" y="28" class="label" id="Bepo">Bepo</text>
@@ -593,7 +608,7 @@ path.combo {
 </g>
 <g transform="translate(546, 97)" class="key keypos-20">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<use href="#material:keyboard_return" xlink:href="#material:keyboard_return" x="-7" y="-7" height="14" width="14.0" class="key tap glyph material:keyboard_return"/>
+<text x="0" y="0" class="key tap"><tspan style="font-size: 86%">ALT_REP</tspan></text>
 </g>
 <g transform="translate(602, 97)" class="key keypos-21">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
@@ -655,7 +670,7 @@ path.combo {
 </g>
 <g transform="translate(378, 153)" class="key keypos-34">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<text x="0" y="0" class="key tap">MUTE</text>
+<text x="0" y="0" class="key tap">REPEAT</text>
 </g>
 <g transform="translate(546, 153)" class="key keypos-35">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
@@ -886,7 +901,7 @@ path.combo {
 </g>
 <g transform="translate(546, 97)" class="key keypos-20">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<use href="#material:keyboard_return" xlink:href="#material:keyboard_return" x="-7" y="-7" height="14" width="14.0" class="key tap glyph material:keyboard_return"/>
+<text x="0" y="0" class="key tap"><tspan style="font-size: 86%">ALT_REP</tspan></text>
 </g>
 <g transform="translate(602, 97)" class="key keypos-21">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
@@ -947,7 +962,7 @@ path.combo {
 </g>
 <g transform="translate(378, 153)" class="key keypos-34">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<text x="0" y="0" class="key tap">MUTE</text>
+<text x="0" y="0" class="key tap">REPEAT</text>
 </g>
 <g transform="translate(546, 153)" class="key keypos-35">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
@@ -1170,7 +1185,7 @@ path.combo {
 </g>
 <g transform="translate(546, 97)" class="key keypos-20">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<use href="#material:keyboard_return" xlink:href="#material:keyboard_return" x="-7" y="-7" height="14" width="14.0" class="key tap glyph material:keyboard_return"/>
+<text x="0" y="0" class="key tap"><tspan style="font-size: 86%">ALT_REP</tspan></text>
 </g>
 <g transform="translate(602, 97)" class="key keypos-21">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
@@ -1230,7 +1245,7 @@ path.combo {
 </g>
 <g transform="translate(378, 153)" class="key keypos-34">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>
-<text x="0" y="0" class="key tap">MUTE</text>
+<text x="0" y="0" class="key tap">REPEAT</text>
 </g>
 <g transform="translate(546, 153)" class="key keypos-35">
 <rect rx="6" ry="6" x="-25" y="-25" width="50" height="50" class="key"/>