From 1e127a93c4c1446cf11aacecc9597a7355262ac8 Mon Sep 17 00:00:00 2001
From: Scott Lahteine <github@thinkyhead.com>
Date: Sat, 4 Jun 2022 00:15:23 -0500
Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=91=E2=80=8D=F0=9F=92=BB=20Extend=20LC?=
 =?UTF-8?q?D=20string=20substitution=20(#24278)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 Marlin/src/feature/dac/stepper_dac.cpp        |   1 -
 Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp   |  10 +-
 Marlin/src/lcd/HD44780/marlinui_HD44780.cpp   |  23 +-
 Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp   |  10 +-
 Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp   | 142 +++++-----
 Marlin/src/lcd/dogm/lcdprint_u8g.cpp          |   6 +-
 Marlin/src/lcd/dogm/marlinui_DOGM.cpp         |  38 +--
 Marlin/src/lcd/dogm/u8g_fontutf8.cpp          |   2 +-
 Marlin/src/lcd/dogm/u8g_fontutf8.h            |   6 +-
 Marlin/src/lcd/e3v2/jyersui/dwin.cpp          |  10 +-
 Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp  |  60 +++--
 Marlin/src/lcd/e3v2/marlinui/dwin_string.h    |  87 ++++--
 .../src/lcd/e3v2/marlinui/lcdprint_dwin.cpp   |  41 ++-
 Marlin/src/lcd/e3v2/marlinui/ui_common.cpp    |  38 ++-
 .../lcd/e3v2/marlinui/ui_status_480x272.cpp   |  10 +-
 Marlin/src/lcd/e3v2/proui/dwin.cpp            |  10 +-
 Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp        |   2 +-
 .../bioprinter/advanced_settings.cpp          |   2 +-
 .../cocoa_press/advanced_settings_menu.cpp    |   2 +-
 .../generic/advanced_settings_menu.cpp        |   2 +-
 .../generic/max_velocity_screen.cpp           |   2 +-
 .../ftdi_eve_touch_ui/language/language.h     |   2 +
 .../ftdi_eve_touch_ui/language/language_en.h  | 254 +++++++++---------
 Marlin/src/lcd/fontutils.cpp                  |  13 +-
 Marlin/src/lcd/fontutils.h                    |  12 +-
 Marlin/src/lcd/language/language_an.h         |  13 +-
 Marlin/src/lcd/language/language_bg.h         |   7 +-
 Marlin/src/lcd/language/language_ca.h         |  11 +-
 Marlin/src/lcd/language/language_cz.h         |  33 +--
 Marlin/src/lcd/language/language_da.h         |  10 +-
 Marlin/src/lcd/language/language_de.h         |  54 +---
 Marlin/src/lcd/language/language_el.h         |  20 +-
 Marlin/src/lcd/language/language_el_gr.h      |  20 +-
 Marlin/src/lcd/language/language_en.h         |  71 ++---
 Marlin/src/lcd/language/language_es.h         |  41 +--
 Marlin/src/lcd/language/language_eu.h         |  19 +-
 Marlin/src/lcd/language/language_fi.h         |   2 +-
 Marlin/src/lcd/language/language_fr.h         |  43 +--
 Marlin/src/lcd/language/language_gl.h         |  40 +--
 Marlin/src/lcd/language/language_hr.h         |   2 +-
 Marlin/src/lcd/language/language_hu.h         |  43 +--
 Marlin/src/lcd/language/language_it.h         |  79 +-----
 Marlin/src/lcd/language/language_jp_kana.h    |  22 +-
 Marlin/src/lcd/language/language_nl.h         |   3 +-
 Marlin/src/lcd/language/language_pl.h         |  25 +-
 Marlin/src/lcd/language/language_pt.h         |   6 +-
 Marlin/src/lcd/language/language_pt_br.h      |  13 +-
 Marlin/src/lcd/language/language_ro.h         |  45 ++--
 Marlin/src/lcd/language/language_ru.h         |  44 +--
 Marlin/src/lcd/language/language_sk.h         |  66 ++---
 Marlin/src/lcd/language/language_sv.h         |  33 +--
 Marlin/src/lcd/language/language_tr.h         |  33 +--
 Marlin/src/lcd/language/language_uk.h         |  44 +--
 Marlin/src/lcd/language/language_vi.h         |  31 +--
 Marlin/src/lcd/language/language_zh_CN.h      |  32 +--
 Marlin/src/lcd/language/language_zh_TW.h      |  32 +--
 Marlin/src/lcd/lcdprint.cpp                   |  19 +-
 Marlin/src/lcd/lcdprint.h                     | 134 +++++++--
 Marlin/src/lcd/marlinui.cpp                   |   5 +-
 Marlin/src/lcd/menu/menu.cpp                  |   7 +-
 Marlin/src/lcd/menu/menu.h                    |  22 +-
 Marlin/src/lcd/menu/menu_advanced.cpp         |  50 ++--
 Marlin/src/lcd/menu/menu_backlash.cpp         |   2 +-
 Marlin/src/lcd/menu/menu_configuration.cpp    |   2 +-
 Marlin/src/lcd/menu/menu_filament.cpp         |  20 +-
 Marlin/src/lcd/menu/menu_item.h               |  80 +++++-
 Marlin/src/lcd/menu/menu_motion.cpp           |  20 +-
 Marlin/src/lcd/menu/menu_probe_offset.cpp     |  17 +-
 Marlin/src/lcd/menu/menu_temperature.cpp      |  24 +-
 Marlin/src/lcd/menu/menu_tune.cpp             |   8 +-
 Marlin/src/lcd/menu/menu_ubl.cpp              |   6 +-
 Marlin/src/lcd/menu/menu_x_twist.cpp          |  11 +-
 Marlin/src/lcd/tft/tft.h                      |   2 +-
 Marlin/src/lcd/tft/tft_queue.cpp              |   4 +-
 Marlin/src/lcd/tft/tft_queue.h                |   5 +-
 Marlin/src/lcd/tft/tft_string.cpp             |  38 +--
 Marlin/src/lcd/tft/tft_string.h               |  87 ++++--
 Marlin/src/lcd/tft/ui_1024x600.cpp            |  10 +-
 Marlin/src/lcd/tft/ui_320x240.cpp             |  10 +-
 Marlin/src/lcd/tft/ui_480x320.cpp             |  10 +-
 Marlin/src/lcd/tft/ui_common.cpp              |  24 +-
 Marlin/src/libs/L64XX/L64XX_Marlin.cpp        |   2 +-
 buildroot/share/fonts/genpages.c              |   2 +-
 83 files changed, 1062 insertions(+), 1281 deletions(-)

diff --git a/Marlin/src/feature/dac/stepper_dac.cpp b/Marlin/src/feature/dac/stepper_dac.cpp
index ff730e93c62..119a8595998 100644
--- a/Marlin/src/feature/dac/stepper_dac.cpp
+++ b/Marlin/src/feature/dac/stepper_dac.cpp
@@ -29,7 +29,6 @@
 #if HAS_MOTOR_CURRENT_DAC
 
 #include "stepper_dac.h"
-#include "../../MarlinCore.h" // for SP_X_LBL...
 
 bool dac_present = false;
 constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
diff --git a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
index 31b26aa5bbc..1e82fe403d9 100644
--- a/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
+++ b/Marlin/src/lcd/HD44780/lcdprint_hd44780.cpp
@@ -992,7 +992,7 @@ void lcd_put_int(const int i) { lcd.print(i); }
 
 // return < 0 on error
 // return the advanced cols
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
 
   // find the HD44780 internal ROM first
   int ret;
@@ -1047,9 +1047,9 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
  *
  * Draw a UTF-8 string
  */
-static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
+static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
   pixel_len_t ret = 0;
-  uint8_t *p = (uint8_t *)utf8_str;
+  const uint8_t *p = (uint8_t *)utf8_str;
   while (ret < max_length) {
     wchar_t ch = 0;
     p = get_utf8_value_cb(p, cb_read_byte, &ch);
@@ -1059,11 +1059,11 @@ static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(u
   return (int)ret;
 }
 
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
+int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
 }
 
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
 }
 
diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
index f70b5b01749..da4db8b2d41 100644
--- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
+++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
@@ -495,12 +495,13 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
 #endif // SHOW_BOOTSCREEN
 
 void MarlinUI::draw_kill_screen() {
-  lcd_put_u8str(0, 0, status_message);
-  lcd_uint_t y = 2;
+  lcd_uint_t x = 0, y = 0;
+  lcd_put_u8str(x, y, status_message);
+  y = 2;
   #if LCD_HEIGHT >= 4
-    lcd_put_u8str(0, y++, GET_TEXT_F(MSG_HALTED));
+    lcd_put_u8str(x, y++, GET_TEXT_F(MSG_HALTED));
   #endif
-  lcd_put_u8str(0, y, GET_TEXT_F(MSG_PLEASE_RESET));
+  lcd_put_u8str(x, y, GET_TEXT_F(MSG_PLEASE_RESET));
 }
 
 //
@@ -1076,24 +1077,24 @@ void MarlinUI::draw_status_screen() {
       int8_t pad = (LCD_WIDTH - plen - vlen) / 2;
       while (--pad >= 0) { lcd_put_wchar(' '); n--; }
     }
-    if (plen) n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n);
+    if (plen) n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
     if (vlen) n -= lcd_put_u8str_max(vstr, n);
     for (; n > 0; --n) lcd_put_wchar(' ');
   }
 
   // Draw a generic menu item with pre_char (if selected) and post_char
-  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) {
+  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char pre_char, const char post_char) {
     lcd_put_wchar(0, row, sel ? pre_char : ' ');
-    uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2);
+    uint8_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2);
     for (; n; --n) lcd_put_wchar(' ');
     lcd_put_wchar(post_char);
   }
 
   // Draw a menu item with a (potentially) editable value
-  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
+  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
     const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
     lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
-    uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen);
+    uint8_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vlen);
     if (vlen) {
       lcd_put_wchar(':');
       for (; n; --n) lcd_put_wchar(' ');
@@ -1102,9 +1103,9 @@ void MarlinUI::draw_status_screen() {
   }
 
   // Low-level draw_edit_screen can be used to draw an edit screen from anyplace
-  void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) {
+  void MenuEditItemBase::draw_edit_screen(FSTR_P const ftpl, const char * const value/*=nullptr*/) {
     ui.encoder_direction_normal();
-    uint8_t n = lcd_put_u8str_ind(0, 1, fstr, itemIndex, itemString, LCD_WIDTH - 1);
+    uint8_t n = lcd_put_u8str(0, 1, ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 1);
     if (value) {
       lcd_put_wchar(':'); n--;
       const uint8_t len = utf8_strlen(value) + 1;   // Plus one for a leading space
diff --git a/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp
index d0cf5795d23..7b15b786055 100644
--- a/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp
+++ b/Marlin/src/lcd/TFTGLCD/lcdprint_TFTGLCD.cpp
@@ -991,7 +991,7 @@ void lcd_put_int(const int i) {
 
 // return < 0 on error
 // return the advanced cols
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
 
   // find the HD44780 internal ROM first
   int ret;
@@ -1045,9 +1045,9 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
  *
  * Draw a UTF-8 string
  */
-static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
+static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
   pixel_len_t ret = 0;
-  uint8_t *p = (uint8_t *)utf8_str;
+  const uint8_t *p = (uint8_t *)utf8_str;
   while (ret < max_length) {
     wchar_t ch = 0;
     p = get_utf8_value_cb(p, cb_read_byte, &ch);
@@ -1057,11 +1057,11 @@ static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(u
   return (int)ret;
 }
 
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
+int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
 }
 
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
 }
 
diff --git a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp
index ca830960cb8..46564bb1e6e 100644
--- a/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp
+++ b/Marlin/src/lcd/TFTGLCD/marlinui_TFTGLCD.cpp
@@ -380,9 +380,13 @@ void MarlinUI::clear_lcd() {
   void MarlinUI::_set_contrast() { lcd.setContrast(contrast); }
 #endif
 
+#if !IS_TFTGLCD_PANEL
+  void lcd_moveto(const uint8_t col, const uint8_t row) { lcd.setCursor(col, row); }
+#endif
+
 static void center_text(FSTR_P const fstart, const uint8_t y) {
   const uint8_t len = utf8_strlen(fstart);
-  lcd.setCursor(len < LCD_WIDTH ? (LCD_WIDTH - len) / 2 : 0, y);
+  lcd_moveto(len < LCD_WIDTH ? (LCD_WIDTH - len) / 2 : 0, y);
   lcd_put_u8str(fstart);
 }
 
@@ -396,9 +400,9 @@ static void center_text(FSTR_P const fstart, const uint8_t y) {
     uint8_t indent = (LCD_WIDTH - 8) / 2;
     // symbols 217 (bottom right corner) and 218 (top left corner) are using for letters in some languages
     // and they should be moved to beginning ASCII table as special symbols
-    lcd.setCursor(indent, 0); lcd.write(TLC); lcd_put_u8str(F("------"));  lcd.write(TRC);
-    lcd.setCursor(indent, 1); lcd.write(LR);  lcd_put_u8str(F("Marlin"));  lcd.write(LR);
-    lcd.setCursor(indent, 2); lcd.write(BLC); lcd_put_u8str(F("------"));  lcd.write(BRC);
+    lcd_moveto(indent, 0); lcd.write(TLC); lcd_put_u8str(F("------")); lcd.write(TRC);
+    lcd_moveto(indent, 1); lcd.write(LR);  lcd_put_u8str(F("Marlin")); lcd.write(LR);
+    lcd_moveto(indent, 2); lcd.write(BLC); lcd_put_u8str(F("------")); lcd.write(BRC);
     center_text(F(SHORT_BUILD_VERSION), 3);
     center_text(F(MARLIN_WEBSITE_URL), 4);
     picBits = ICON_LOGO;
@@ -414,8 +418,8 @@ static void center_text(FSTR_P const fstart, const uint8_t y) {
 void MarlinUI::draw_kill_screen() {
   if (!PanelDetected) return;
   lcd.clear_buffer();
-  lcd.setCursor(0, 3);  lcd.write(COLOR_ERROR);
-  lcd.setCursor((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3);
+  lcd_moveto(0, 3); lcd.write(COLOR_ERROR);
+  lcd_moveto((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3);
   lcd_put_u8str(status_message);
   center_text(GET_TEXT_F(MSG_HALTED), 5);
   center_text(GET_TEXT_F(MSG_PLEASE_RESET), 6);
@@ -453,25 +457,25 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 
     #if HOTENDS < 2
       if (heater_id == H_E0) {
-        lcd.setCursor(2, 5);  lcd.print(prefix); //HE
-        lcd.setCursor(1, 6);  lcd.print(i16tostr3rj(t1));
-        lcd.setCursor(1, 7);
+        lcd_moveto(2, 5); lcd.print(prefix); //HE
+        lcd_moveto(1, 6); lcd.print(i16tostr3rj(t1));
+        lcd_moveto(1, 7);
       }
       else {
-        lcd.setCursor(6, 5);  lcd.print(prefix); //BED
-        lcd.setCursor(6, 6);  lcd.print(i16tostr3rj(t1));
-        lcd.setCursor(6, 7);
+        lcd_moveto(6, 5); lcd.print(prefix); //BED
+        lcd_moveto(6, 6); lcd.print(i16tostr3rj(t1));
+        lcd_moveto(6, 7);
       }
     #else
       if (heater_id > H_BED) {
-        lcd.setCursor(heater_id * 4, 5);  lcd.print(prefix); // HE1 or HE2 or HE3
-        lcd.setCursor(heater_id * 4, 6);  lcd.print(i16tostr3rj(t1));
-        lcd.setCursor(heater_id * 4, 7);
+        lcd_moveto(heater_id * 4, 5); lcd.print(prefix); // HE1 or HE2 or HE3
+        lcd_moveto(heater_id * 4, 6); lcd.print(i16tostr3rj(t1));
+        lcd_moveto(heater_id * 4, 7);
       }
       else {
-        lcd.setCursor(13, 5);  lcd.print(prefix); //BED
-        lcd.setCursor(13, 6);  lcd.print(i16tostr3rj(t1));
-        lcd.setCursor(13, 7);
+        lcd_moveto(13, 5); lcd.print(prefix); //BED
+        lcd_moveto(13, 6); lcd.print(i16tostr3rj(t1));
+        lcd_moveto(13, 7);
       }
     #endif // HOTENDS <= 1
 
@@ -512,9 +516,9 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
   FORCE_INLINE void _draw_cooler_status(const bool blink) {
     const celsius_t t2 = thermalManager.degTargetCooler();
 
-    lcd.setCursor(0, 5); lcd_put_u8str(F("COOL"));
-    lcd.setCursor(1, 6); lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
-    lcd.setCursor(1, 7);
+    lcd_moveto(0, 5); lcd_put_u8str(F("COOL"));
+    lcd_moveto(1, 6); lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
+    lcd_moveto(1, 7);
 
     #if !HEATER_IDLE_HANDLER
       UNUSED(blink);
@@ -540,9 +544,9 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 #if ENABLED(LASER_COOLANT_FLOW_METER)
 
   FORCE_INLINE void _draw_flowmeter_status() {
-    lcd.setCursor(5, 5); lcd_put_u8str(F("FLOW"));
-    lcd.setCursor(7, 6); lcd_put_wchar('L');
-    lcd.setCursor(6, 7); lcd_put_u8str(ftostr11ns(cooler.flowrate));
+    lcd_moveto(5, 5); lcd_put_u8str(F("FLOW"));
+    lcd_moveto(7, 6); lcd_put_wchar('L');
+    lcd_moveto(6, 7); lcd_put_u8str(ftostr11ns(cooler.flowrate));
 
     if (cooler.flowrate)  picBits |= ICON_FAN;
     else                  picBits &= ~ICON_FAN;
@@ -553,18 +557,18 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 #if ENABLED(I2C_AMMETER)
 
   FORCE_INLINE void _draw_ammeter_status() {
-    lcd.setCursor(10, 5); lcd_put_u8str(F("ILAZ"));
+    lcd_moveto(10, 5); lcd_put_u8str(F("ILAZ"));
     ammeter.read();
-    lcd.setCursor(11, 6);
+    lcd_moveto(11, 6);
     if (ammeter.current <= 0.999f)
     {
       lcd_put_u8str("mA");
-      lcd.setCursor(10, 7);
+      lcd_moveto(10, 7);
       lcd_put_wchar(' '); lcd_put_u8str(ui16tostr3rj(uint16_t(ammeter.current * 1000 + 0.5f)));
     }
     else {
       lcd_put_u8str(" A");
-      lcd.setCursor(10, 7);
+      lcd_moveto(10, 7);
       lcd_put_u8str(ftostr12ns(ammeter.current));
     }
 
@@ -577,16 +581,16 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 #if HAS_CUTTER
 
   FORCE_INLINE void _draw_cutter_status() {
-    lcd.setCursor(15, 5);  lcd_put_u8str(F("CUTT"));
+    lcd_moveto(15, 5);  lcd_put_u8str(F("CUTT"));
     #if CUTTER_UNIT_IS(RPM)
-      lcd.setCursor(16, 6);  lcd_put_u8str(F("RPM"));
-      lcd.setCursor(15, 7);  lcd_put_u8str(ftostr31ns(float(cutter.unitPower) / 1000));
+      lcd_moveto(16, 6);  lcd_put_u8str(F("RPM"));
+      lcd_moveto(15, 7);  lcd_put_u8str(ftostr31ns(float(cutter.unitPower) / 1000));
       lcd_put_wchar('K');
     #elif CUTTER_UNIT_IS(PERCENT)
-      lcd.setCursor(17, 6);  lcd_put_wchar('%');
-      lcd.setCursor(18, 7);  lcd_put_u8str(cutter_power2str(cutter.unitPower));
+      lcd_moveto(17, 6);  lcd_put_wchar('%');
+      lcd_moveto(18, 7);  lcd_put_u8str(cutter_power2str(cutter.unitPower));
     #else
-      lcd.setCursor(17, 7);  lcd_put_u8str(cutter_power2str(cutter.unitPower));
+      lcd_moveto(17, 7);  lcd_put_u8str(cutter_power2str(cutter.unitPower));
     #endif
 
     if (cutter.unitPower) picBits |= ICON_HOT;
@@ -622,10 +626,10 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
       lcd.write('%'); lcd.write(percent);
     }
     else { // For progress bar test
-      lcd.setCursor(LCD_WIDTH / 2 - 2, MIDDLE_Y);
-      lcd.print(i16tostr3rj(percent));  lcd.write('%');
+      lcd_moveto(LCD_WIDTH / 2 - 2, MIDDLE_Y);
+      lcd.print(i16tostr3rj(percent)); lcd.write('%');
       lcd.print_line();
-      lcd.setCursor(0, MIDDLE_Y + 1);
+      lcd_moveto(0, MIDDLE_Y + 1);
       lcd.write('%'); lcd.write(percent);
       lcd.print_line();
     }
@@ -635,7 +639,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 
 void MarlinUI::draw_status_message(const bool blink) {
   if (!PanelDetected) return;
-  lcd.setCursor(0, 3);
+  lcd_moveto(0, 3);
   #if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT)
 
     // Alternate Status message and Filament display
@@ -784,7 +788,7 @@ void MarlinUI::draw_status_screen() {
   // Line 1 - XYZ coordinates
   //
 
-  lcd.setCursor(0, 0);
+  lcd_moveto(0, 0);
   const xyz_pos_t lpos = current_position.asLogical();
   _draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); lcd.write(' ');
   _draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); lcd.write(' ');
@@ -798,11 +802,11 @@ void MarlinUI::draw_status_screen() {
   // Line 2 - feedrate, , time
   //
 
-  lcd.setCursor(0, 1);
+  lcd_moveto(0, 1);
   lcd_put_u8str(F("FR")); lcd.print(i16tostr3rj(feedrate_percentage)); lcd.write('%');
 
   #if BOTH(SDSUPPORT, HAS_PRINT_PROGRESS)
-    lcd.setCursor(LCD_WIDTH / 2 - 3, 1);
+    lcd_moveto(LCD_WIDTH / 2 - 3, 1);
     _draw_print_progress();
   #endif
 
@@ -810,14 +814,14 @@ void MarlinUI::draw_status_screen() {
   duration_t elapsed = print_job_timer.duration();
   uint8_t len = elapsed.toDigital(buffer);
 
-  lcd.setCursor((LCD_WIDTH - 1) - len, 1);
+  lcd_moveto((LCD_WIDTH - 1) - len, 1);
   lcd.write(LCD_STR_CLOCK[0]); lcd.print(buffer);
 
   //
   // Line 3 - progressbar
   //
 
-  lcd.setCursor(0, 2);
+  lcd_moveto(0, 2);
   #if ENABLED(LCD_PROGRESS_BAR)
     draw_progress_bar(_get_progress());
   #else
@@ -836,7 +840,7 @@ void MarlinUI::draw_status_screen() {
 
   #if HOTENDS <= 1 || (HOTENDS <= 2 && !HAS_HEATED_BED)
     #if DUAL_MIXING_EXTRUDER
-      lcd.setCursor(0, 4);
+      lcd_moveto(0, 4);
       // Two-component mix / gradient instead of XY
       char mixer_messages[12];
       const char *mix_label;
@@ -892,9 +896,9 @@ void MarlinUI::draw_status_screen() {
       #else
         #define FANX 17
       #endif
-      lcd.setCursor(FANX, 5); lcd_put_u8str(F("FAN"));
-      lcd.setCursor(FANX + 1, 6); lcd.write('%');
-      lcd.setCursor(FANX, 7);
+      lcd_moveto(FANX, 5); lcd_put_u8str(F("FAN"));
+      lcd_moveto(FANX + 1, 6); lcd.write('%');
+      lcd_moveto(FANX, 7);
       lcd.print(i16tostr3rj(per));
 
       if (TERN0(HAS_FAN0, thermalManager.fan_speed[0]) || TERN0(HAS_FAN1, thermalManager.fan_speed[1]) || TERN0(HAS_FAN2, thermalManager.fan_speed[2]))
@@ -927,7 +931,7 @@ void MarlinUI::draw_status_screen() {
 
     void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) {
       if (!PanelDetected) return;
-      lcd.setCursor((LCD_WIDTH - 14) / 2, row + 1);
+      lcd_moveto((LCD_WIDTH - 14) / 2, row + 1);
       lcd.write(LCD_STR_THERMOMETER[0]); lcd_put_u8str(F(" E")); lcd.write('1' + extruder); lcd.write(' ');
       lcd.print(i16tostr3rj(thermalManager.wholeDegHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]); lcd.write('/');
       lcd.print(i16tostr3rj(thermalManager.degTargetHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]);
@@ -940,12 +944,12 @@ void MarlinUI::draw_status_screen() {
   void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
     if (!PanelDetected) return;
     uint8_t n = LCD_WIDTH;
-    lcd.setCursor(0, row);
+    lcd_moveto(0, row);
     if ((style & SS_CENTER) && !valstr) {
       int8_t pad = (LCD_WIDTH - utf8_strlen(fstr)) / 2;
       while (--pad >= 0) { lcd.write(' '); n--; }
     }
-    n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n);
+    n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
     if (valstr) n -= lcd_put_u8str_max(valstr, n);
     for (; n; --n) lcd.write(' ');
     lcd.print_line();
@@ -954,25 +958,25 @@ void MarlinUI::draw_status_screen() {
   // Draw a generic menu item with pre_char (if selected) and post_char
   void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) {
     if (!PanelDetected) return;
-    lcd.setCursor(0, row);
+    lcd_moveto(0, row);
     lcd.write(sel ? pre_char : ' ');
-    uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2);
+    uint8_t n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2);
     for (; n; --n) lcd.write(' ');
     lcd.write(post_char);
     lcd.print_line();
   }
 
   // Draw a menu item with a (potentially) editable value
-  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const data, const bool pgm) {
+  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
     if (!PanelDetected) return;
-    const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0;
-    lcd.setCursor(0, row);
+    const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
+    lcd_moveto(0, row);
     lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
-    uint8_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen);
+    uint8_t n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vlen);
     if (vlen) {
       lcd.write(':');
       for (; n; --n) lcd.write(' ');
-      if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
+      if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
     }
     lcd.print_line();
   }
@@ -983,12 +987,12 @@ void MarlinUI::draw_status_screen() {
     if (!PanelDetected) return;
     ui.encoder_direction_normal();
     const uint8_t y = TERN0(AUTO_BED_LEVELING_UBL, ui.external_control) ? LCD_HEIGHT - 1 : MIDDLE_Y;
-    lcd.setCursor(0, y);
+    lcd_moveto(0, y);
     lcd.write(COLOR_EDIT);
     lcd_put_u8str(fstr);
     if (value) {
       lcd.write(':');
-      lcd.setCursor((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces
+      lcd_moveto((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces
       lcd.write(' ');                                               // Overwrite char if value gets shorter
       lcd.print(value);
       lcd.write(' ');
@@ -1002,11 +1006,11 @@ void MarlinUI::draw_status_screen() {
     ui.draw_select_screen_prompt(pref, string, suff);
     lcd.write(COLOR_EDIT);
     if (no) {
-      lcd.setCursor(0, MIDDLE_Y);
+      lcd_moveto(0, MIDDLE_Y);
       lcd.write(yesno ? ' ' : '['); lcd_put_u8str(no); lcd.write(yesno ? ' ' : ']');
     }
     if (yes) {
-      lcd.setCursor(LCD_WIDTH - utf8_strlen(yes) - 3, MIDDLE_Y);
+      lcd_moveto(LCD_WIDTH - utf8_strlen(yes) - 3, MIDDLE_Y);
       lcd.write(yesno ? '[' : ' '); lcd_put_u8str(yes); lcd.write(yesno ? ']' : ' ');
     }
     lcd.print_line();
@@ -1016,7 +1020,7 @@ void MarlinUI::draw_status_screen() {
 
     void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
       if (!PanelDetected) return;
-      lcd.setCursor(0, row);
+      lcd_moveto(0, row);
       lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
       constexpr uint8_t maxlen = LCD_WIDTH - 2;
       uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
@@ -1055,23 +1059,23 @@ void MarlinUI::draw_status_screen() {
       lcd.clear_buffer();
 
       //print only top left corner. All frame with grid points will be printed by panel
-      lcd.setCursor(0, 0);
+      lcd_moveto(0, 0);
       *fb++ = TLC;   //top left corner - marker for plot parameters
       *fb = (GRID_MAX_POINTS_X << 4) + GRID_MAX_POINTS_Y; //set mesh size
 
       // Print plot position
-      lcd.setCursor(_LCD_W_POS, 0);
-      *fb++ = '(';  lcd.print(i16tostr3left(x_plot));
-      *fb++ = ',';  lcd.print(i16tostr3left(y_plot)); *fb = ')';
+      lcd_moveto(_LCD_W_POS, 0);
+      *fb++ = '('; lcd.print(i16tostr3left(x_plot));
+      *fb++ = ','; lcd.print(i16tostr3left(y_plot)); *fb = ')';
 
       // Show all values
-      lcd.setCursor(_LCD_W_POS, 1); lcd_put_u8str(F("X:"));
+      lcd_moveto(_LCD_W_POS, 1); lcd_put_u8str(F("X:"));
       lcd.print(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&bedlevel._mesh_index_to_xpos[x_plot]))));
-      lcd.setCursor(_LCD_W_POS, 2); lcd_put_u8str(F("Y:"));
+      lcd_moveto(_LCD_W_POS, 2); lcd_put_u8str(F("Y:"));
       lcd.print(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&bedlevel._mesh_index_to_ypos[y_plot]))));
 
       // Show the location value
-      lcd.setCursor(_LCD_W_POS, 3); lcd_put_u8str(F("Z:"));
+      lcd_moveto(_LCD_W_POS, 3); lcd_put_u8str(F("Z:"));
 
       if (!isnan(bedlevel.z_values[x_plot][y_plot]))
         lcd.print(ftostr43sign(bedlevel.z_values[x_plot][y_plot]));
diff --git a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
index f74a59a08c7..f5c13798f23 100644
--- a/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
+++ b/Marlin/src/lcd/dogm/lcdprint_u8g.cpp
@@ -28,7 +28,7 @@ void lcd_put_int(const int i) { u8g.print(i); }
 
 // return < 0 on error
 // return the advanced pixels
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
   if (c < 256) {
     u8g.print((char)c);
     return u8g_GetFontBBXWidth(u8g.getU8g());
@@ -39,14 +39,14 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
   return ret;
 }
 
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
+int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
   u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
            ret = uxg_DrawUtf8Str(u8g.getU8g(), x, y, utf8_str, max_length);
   u8g.setPrintPos(x + ret, y);
   return ret;
 }
 
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
   u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
            ret = uxg_DrawUtf8StrP(u8g.getU8g(), x, y, utf8_pstr, max_length);
   u8g.setPrintPos(x + ret, y);
diff --git a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
index 3b40343628b..3c661a44294 100644
--- a/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/marlinui_DOGM.cpp
@@ -330,13 +330,13 @@ void MarlinUI::update_language_font() {
 // The kill screen is displayed for unrecoverable conditions
 void MarlinUI::draw_kill_screen() {
   TERN_(LIGHTWEIGHT_UI, ST7920_Lite_Status_Screen::clear_text_buffer());
-  const u8g_uint_t h4 = u8g.getHeight() / 4;
+  const u8g_uint_t x = 0, h4 = u8g.getHeight() / 4;
   u8g.firstPage();
   do {
     set_font(FONT_MENU);
-    lcd_put_u8str(0, h4 * 1, status_message);
-    lcd_put_u8str(0, h4 * 2, GET_TEXT_F(MSG_HALTED));
-    lcd_put_u8str(0, h4 * 3, GET_TEXT_F(MSG_PLEASE_RESET));
+    lcd_put_u8str(x, h4 * 1, status_message);
+    lcd_put_u8str(x, h4 * 2, GET_TEXT_F(MSG_HALTED));
+    lcd_put_u8str(x, h4 * 3, GET_TEXT_F(MSG_PLEASE_RESET));
   } while (u8g.nextPage());
 }
 
@@ -412,28 +412,28 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
   }
 
   // Draw a static line of text in the same idiom as a menu item
-  void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
+  void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
 
     if (mark_as_selected(row, style & SS_INVERT)) {
       pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
 
-      const int plen = fstr ? calculateWidth(FTOP(fstr)) : 0,
+      const int plen = ftpl ? calculateWidth(ftpl) : 0,
                 vlen = vstr ? utf8_strlen(vstr) : 0;
       if (style & SS_CENTER) {
         int pad = (LCD_PIXEL_WIDTH - plen - vlen * MENU_FONT_WIDTH) / MENU_FONT_WIDTH / 2;
         while (--pad >= 0) n -= lcd_put_wchar(' ');
       }
 
-      if (plen) n = lcd_put_u8str_ind(fstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH);
+      if (plen) n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH);
       if (vlen) n -= lcd_put_u8str_max(vstr, n);
       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
     }
   }
 
   // Draw a generic menu item
-  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char, const char post_char) {
+  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
     if (mark_as_selected(row, sel)) {
-      pixel_len_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH);
+      pixel_len_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 1) * (MENU_FONT_WIDTH);
       while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
       lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char);
       lcd_put_wchar(' ');
@@ -441,27 +441,27 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
   }
 
   // Draw a menu item with an editable value
-  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
+  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
     if (mark_as_selected(row, sel)) {
-      const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen((char*)inStr)),
-                    pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), (char*)inStr));
+      const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)),
+                    pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr));
       const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
 
-      pixel_len_t n = lcd_put_u8str_ind(fstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH);
+      pixel_len_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH);
       if (vallen) {
         lcd_put_wchar(':');
         while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
         lcd_moveto(LCD_PIXEL_WIDTH - _MAX((MENU_FONT_WIDTH) * vallen, pixelwidth + 2), row_y2);
-        if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str((char*)inStr);
+        if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
       }
     }
   }
 
-  void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) {
+  void MenuEditItemBase::draw_edit_screen(FSTR_P const ftpl, const char * const value/*=nullptr*/) {
     ui.encoder_direction_normal();
 
     const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
-    const u8g_uint_t labellen = utf8_strlen(fstr), vallen = utf8_strlen(value);
+    const u8g_uint_t labellen = utf8_strlen(ftpl), vallen = utf8_strlen(value);
     bool extra_row = labellen * prop > LCD_WIDTH - 2 - vallen * prop;
 
     #if ENABLED(USE_BIG_EDIT_FONT)
@@ -490,7 +490,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
 
     // Assume the label is alpha-numeric (with a descender)
     bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT);
-    if (onpage) lcd_put_u8str_ind(0, baseline, fstr, itemIndex, itemString);
+    if (onpage) lcd_put_u8str(0, baseline, ftpl, itemIndex, itemStringC, itemStringF);
 
     // If a value is included, print a colon, then print the value right-justified
     if (value) {
@@ -522,8 +522,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
     if (inv) u8g.setColorIndex(1);
   }
 
-  void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) {
-    ui.draw_select_screen_prompt(pref, string, suff);
+  void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const fpre, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) {
+    ui.draw_select_screen_prompt(fpre, string, suff);
     if (no)  draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno);
     if (yes) draw_boxed_string(LCD_WIDTH - (utf8_strlen(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno);
   }
diff --git a/Marlin/src/lcd/dogm/u8g_fontutf8.cpp b/Marlin/src/lcd/dogm/u8g_fontutf8.cpp
index 89bdb09e1be..8ba0e7d50a8 100644
--- a/Marlin/src/lcd/dogm/u8g_fontutf8.cpp
+++ b/Marlin/src/lcd/dogm/u8g_fontutf8.cpp
@@ -104,7 +104,7 @@ static void fontgroup_drawwchar(font_group_t *group, const font_t *fnt_default,
  * Get the screen pixel width of a ROM UTF-8 string
  */
 static void fontgroup_drawstring(font_group_t *group, const font_t *fnt_default, const char *utf8_msg, read_byte_cb_t cb_read_byte, void * userdata, fontgroup_cb_draw_t cb_draw_ram) {
-  uint8_t *p = (uint8_t*)utf8_msg;
+  const uint8_t *p = (uint8_t*)utf8_msg;
   for (;;) {
     wchar_t val = 0;
     p = get_utf8_value_cb(p, cb_read_byte, &val);
diff --git a/Marlin/src/lcd/dogm/u8g_fontutf8.h b/Marlin/src/lcd/dogm/u8g_fontutf8.h
index 9760ef106bd..5933f027cc7 100644
--- a/Marlin/src/lcd/dogm/u8g_fontutf8.h
+++ b/Marlin/src/lcd/dogm/u8g_fontutf8.h
@@ -26,10 +26,10 @@ typedef struct _uxg_fontinfo_t {
 
 int uxg_SetUtf8Fonts(const uxg_fontinfo_t * fntinfo, int number); // fntinfo is type of PROGMEM
 
-unsigned int uxg_DrawWchar(u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, pixel_len_t max_length);
+unsigned int uxg_DrawWchar(u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, const pixel_len_t max_length);
 
-unsigned int uxg_DrawUtf8Str(u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
-unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, PGM_P utf8_msg, pixel_len_t max_length);
+unsigned int uxg_DrawUtf8Str(u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, const pixel_len_t max_length);
+unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, PGM_P utf8_msg, const pixel_len_t max_length);
 
 int uxg_GetUtf8StrPixelWidth(u8g_t *pu8g, const char *utf8_msg);
 int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, PGM_P utf8_msg);
diff --git a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp
index f8ba1090d91..19155fd5e55 100644
--- a/Marlin/src/lcd/e3v2/jyersui/dwin.cpp
+++ b/Marlin/src/lcd/e3v2/jyersui/dwin.cpp
@@ -4280,14 +4280,14 @@ void CrealityDWINClass::Print_Screen_Control() {
               card.startOrResumeFilePrinting();
               TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
             #else
-              char cmnd[20];
+              char cmd[20];
               #if HAS_HEATED_BED
-                cmnd[sprintf_P(cmnd, PSTR("M140 S%i"), pausebed)] = '\0';
-                gcode.process_subcommands_now(cmnd);
+                sprintf_P(cmd, PSTR("M140 S%i"), pausebed);
+                gcode.process_subcommands_now(cmd);
               #endif
               #if HAS_EXTRUDERS
-                cmnd[sprintf_P(cmnd, PSTR("M109 S%i"), pausetemp)] = '\0';
-                gcode.process_subcommands_now(cmnd);
+                sprintf_P(cmd, PSTR("M109 S%i"), pausetemp);
+                gcode.process_subcommands_now(cmd);
               #endif
               TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan);
               planner.synchronize();
diff --git a/Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp b/Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp
index 4231c4d75f0..d631cbfafc8 100644
--- a/Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp
+++ b/Marlin/src/lcd/e3v2/marlinui/dwin_string.cpp
@@ -27,35 +27,35 @@
 #include "dwin_string.h"
 //#include "../../fontutils.h"
 
-uint8_t DWIN_String::data[];
+char DWIN_String::data[];
 uint16_t DWIN_String::span;
-uint8_t DWIN_String::len;
+uint8_t DWIN_String::length;
 
 void DWIN_String::set() {
   //*data = 0x00;
   memset(data, 0x00, sizeof(data));
   span = 0;
-  len = 0;
+  length = 0;
 }
 
-uint8_t read_byte(uint8_t *byte) { return *byte; }
+uint8_t read_byte(const uint8_t *byte) { return *byte; }
 
 /**
  * Add a string, applying substitutions for the following characters:
  *
- *   $ displays the clipped C-string given by the inStr argument
+ *   $ displays the clipped string given by fstr or cstr
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
  *   @ displays an axis name such as XYZUVW, or E for an extruder
  */
-void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *inStr/*=nullptr*/) {
+void DWIN_String::add(const char *tpl, const int8_t index, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/) {
   wchar_t wchar;
 
-  while (*string) {
-    string = get_utf8_value_cb(string, read_byte, &wchar);
+  while (*tpl) {
+    tpl = get_utf8_value_cb(tpl, read_byte, &wchar);
     if (wchar > 255) wchar |= 0x0080;
-    uint8_t ch = uint8_t(wchar & 0x00FF);
+    const uint8_t ch = uint8_t(wchar & 0x00FF);
 
     if (ch == '=' || ch == '~' || ch == '*') {
       if (index >= 0) {
@@ -65,10 +65,12 @@ void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *inStr/*=null
         add_character('0' + inum);
       }
       else
-        add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED));
+        add(index == -2 ? GET_TEXT_F(MSG_CHAMBER) : GET_TEXT_F(MSG_BED));
     }
-    else if (ch == '$' && inStr)
-      add(inStr);
+    else if (ch == '$' && fstr)
+      add(fstr);
+    else if (ch == '$' && cstr)
+      add(cstr);
     else if (ch == '@')
       add_character(axis_codes[index]);
     else
@@ -77,10 +79,10 @@ void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *inStr/*=null
   eol();
 }
 
-void DWIN_String::add(uint8_t *string, uint8_t max_len) {
+void DWIN_String::add(const char *cstr, uint8_t max_len/*=MAX_STRING_LENGTH*/) {
   wchar_t wchar;
-  while (*string && max_len) {
-    string = get_utf8_value_cb(string, read_byte, &wchar);
+  while (*cstr && max_len) {
+    cstr = get_utf8_value_cb(cstr, read_byte, &wchar);
     /*
     if (wchar > 255) wchar |= 0x0080;
     uint8_t ch = uint8_t(wchar & 0x00FF);
@@ -92,7 +94,7 @@ void DWIN_String::add(uint8_t *string, uint8_t max_len) {
   eol();
 }
 
-void DWIN_String::add(wchar_t character) {
+void DWIN_String::add(const wchar_t character) {
   int ret;
   size_t idx = 0;
   dwin_charmap_t pinval;
@@ -127,18 +129,18 @@ void DWIN_String::add(wchar_t character) {
   if (str[1]) add_character(str[1]);
 }
 
-void DWIN_String::add_character(const uint8_t character) {
-  if (len < MAX_STRING_LENGTH) {
-    data[len] = character;
-    len++;
+void DWIN_String::add_character(const char character) {
+  if (length < MAX_STRING_LENGTH) {
+    data[length] = character;
+    length++;
     //span += glyph(character)->DWidth;
   }
 }
 
-void DWIN_String::rtrim(const uint8_t character) {
-  while (len) {
-    if (data[len - 1] == 0x20 || data[len - 1] == character) {
-      len--;
+void DWIN_String::rtrim(const char character) {
+  while (length) {
+    if (data[length - 1] == 0x20 || data[length - 1] == character) {
+      length--;
       //span -= glyph(data[length])->DWidth;
       eol();
     }
@@ -147,18 +149,18 @@ void DWIN_String::rtrim(const uint8_t character) {
   }
 }
 
-void DWIN_String::ltrim(const uint8_t character) {
+void DWIN_String::ltrim(const char character) {
   uint16_t i, j;
-  for (i = 0; (i < len) && (data[i] == 0x20 || data[i] == character); i++) {
+  for (i = 0; (i < length) && (data[i] == 0x20 || data[i] == character); i++) {
     //span -= glyph(data[i])->DWidth;
   }
   if (i == 0) return;
-  for (j = 0; i < len; data[j++] = data[i++]);
-  len = j;
+  for (j = 0; i < length; data[j++] = data[i++]);
+  length = j;
   eol();
 }
 
-void DWIN_String::trim(const uint8_t character) {
+void DWIN_String::trim(const char character) {
   rtrim(character);
   ltrim(character);
 }
diff --git a/Marlin/src/lcd/e3v2/marlinui/dwin_string.h b/Marlin/src/lcd/e3v2/marlinui/dwin_string.h
index d013d56a870..c29777ae7b1 100644
--- a/Marlin/src/lcd/e3v2/marlinui/dwin_string.h
+++ b/Marlin/src/lcd/e3v2/marlinui/dwin_string.h
@@ -21,6 +21,8 @@
  */
 #pragma once
 
+// TODO: Make AVR-compatible with separate ROM / RAM string methods
+
 #include "../../fontutils.h"
 #include "../../marlinui.h"
 
@@ -41,14 +43,14 @@ class DWIN_String {
     //static glyph_t *glyphs[256];
     //static font_t *font_header;
 
-    static uint8_t data[MAX_STRING_LENGTH + 1];
+    static char data[MAX_STRING_LENGTH + 1];
     static uint16_t span;   // in pixels
-    static uint8_t len;  // in characters
 
-    static void add_character(const uint8_t character);
-    static void eol() { data[len] = 0x00; }
+    static void add_character(const char character);
+    static void eol() { data[length] = 0x00; }
 
   public:
+    static uint8_t length;  // in characters
     //static void set_font(const uint8_t *font);
     //static void add_glyphs(const uint8_t *font);
 
@@ -57,34 +59,71 @@ class DWIN_String {
     //static glyph_t *glyph(uint8_t character) { return glyphs[character] ?: glyphs[0x3F]; }  /* Use '?' for unknown glyphs */
     //static glyph_t *glyph(uint8_t *character) { return glyph(*character); }
 
+    /**
+     * @brief Set the string empty
+     */
     static void set();
-    //static void add(uint8_t character) { add_character(character); eol(); }
+
+    //static void add(const char character) { add_character(character); eol(); }
+
+    /**
+     * @brief Append a UTF-8 character
+     *
+     * @param character The UTF-8 character
+     */
     static void add(wchar_t character);
-    static void add(uint8_t *string, uint8_t max_len=MAX_STRING_LENGTH);
-    static void add(uint8_t *string, const int8_t index, uint8_t *inStr=nullptr);
-    static void set(uint8_t *string)   { set(); add(string); }
     static void set(wchar_t character) { set(); add(character); }
-    static void set(uint8_t *string, int8_t index, const char *inStr=nullptr) { set(); add(string, index, (uint8_t *)inStr); }
-    static void set(const char *string) { set((uint8_t *)string); }
-    static void set(const char *string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)string, index, inStr); }
-    static void add(const char *string) { add((uint8_t *)string); }
 
-    static void add(FSTR_P const string, uint8_t max_len=MAX_STRING_LENGTH) { add((uint8_t *)FTOP(string), max_len); }
-    static void add(FSTR_P const string, int8_t index, uint8_t *inStr=nullptr) { add((uint8_t *)FTOP(string), index, inStr); }
-    static void set(FSTR_P const string) { set((uint8_t *)FTOP(string)); }
-    static void set(FSTR_P const string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)FTOP(string), index, inStr); }
-    static void add(FSTR_P const string) { add((uint8_t *)FTOP(string)); }
+    /**
+     * @brief Append / Set C-string
+     *
+     * @param cstr The string
+     * @param max_len Character limit
+     */
+    static void add(const char *cstr, uint8_t max_len=MAX_STRING_LENGTH);
+    static void set(const char *cstr) { set(); add(cstr); }
 
-    static void trim(const uint8_t character=0x20);
-    static void rtrim(const uint8_t character=0x20);
-    static void ltrim(const uint8_t character=0x20);
+    /**
+     * @brief Append / Set F-string
+     *
+     * @param fstr The string
+     * @param max_len Character limit
+     */
+    static void add(FSTR_P const fstr, uint8_t max_len=MAX_STRING_LENGTH) { add(FTOP(fstr), max_len); }
+    static void set(FSTR_P const fstr) { set(FTOP(fstr)); }
 
-    static void truncate(uint8_t maxlen) { if (len > maxlen) { len = maxlen; eol(); } }
+    /**
+     * @brief Append / Set C-string with optional substitution
+     *
+     * @param tpl A string with optional substitution
+     * @param index An index
+     * @param cstr An SRAM C-string to use for $ substitution
+     * @param fstr A ROM F-string to use for $ substitution
+     */
+    static void add(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr);
+    static void set(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(tpl, index, cstr, fstr); }
 
-    static uint8_t length() { return len; }
+    /**
+     * @brief Append / Set F-string with optional substitution
+     *
+     * @param ftpl A ROM F-string with optional substitution
+     * @param index An index
+     * @param cstr An SRAM C-string to use for $ substitution
+     * @param fstr A ROM F-string to use for $ substitution
+     */
+    static void add(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { add(FTOP(ftpl), index, cstr, fstr); }
+    static void set(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(ftpl, index, cstr, fstr); }
+
+    // Common string ops
+    static void trim(const char character=' ');
+    static void rtrim(const char character=' ');
+    static void ltrim(const char character=' ');
+    static void truncate(const uint8_t maxlen) { if (length > maxlen) { length = maxlen; eol(); } }
+
+    // Accessors
+    static char *string() { return data; }
     static uint16_t width() { return span; }
-    static uint8_t *string() { return data; }
-    static uint16_t center(uint16_t width) { return span > width ? 0 : (width - span) / 2; }
+    static uint16_t center(const uint16_t width) { return span > width ? 0 : (width - span) / 2; }
 };
 
 int dwin_charmap_compare(dwin_charmap_t *v1, dwin_charmap_t *v2);
diff --git a/Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp b/Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp
index 44be749d41f..278f17fac99 100644
--- a/Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp
+++ b/Marlin/src/lcd/e3v2/marlinui/lcdprint_dwin.cpp
@@ -56,20 +56,20 @@ void lcd_put_int(const int i) {
 }
 
 int lcd_put_dwin_string() {
-  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
-  lcd_advance_cursor(dwin_string.length());
-  return dwin_string.length();
+  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
+  lcd_advance_cursor(dwin_string.length);
+  return dwin_string.length;
 }
 
 // return < 0 on error
 // return the advanced cols
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
   dwin_string.set(c);
   dwin_string.truncate(max_length);
   // Draw the char(s) at the cursor and advance the cursor
-  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
-  lcd_advance_cursor(dwin_string.length());
-  return dwin_string.length();
+  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
+  lcd_advance_cursor(dwin_string.length);
+  return dwin_string.length;
 }
 
 /**
@@ -83,35 +83,34 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
  *
  * Draw a UTF-8 string
  */
-static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
-  uint8_t *p = (uint8_t *)utf8_str;
+static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
+  const uint8_t *p = (uint8_t *)utf8_str;
   dwin_string.set();
-  while (dwin_string.length() < max_length) {
+  while (dwin_string.length < max_length) {
     wchar_t ch = 0;
     p = get_utf8_value_cb(p, cb_read_byte, &ch);
     if (!ch) break;
     dwin_string.add(ch);
   }
-  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
-  lcd_advance_cursor(dwin_string.length());
-  return dwin_string.length();
+  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
+  lcd_advance_cursor(dwin_string.length);
+  return dwin_string.length;
 }
 
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
+int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
 }
 
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
   return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
 }
 
-lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
-  dwin_string.set();
-  dwin_string.add((uint8_t*)pstr, ind, (uint8_t*)inStr);
+lcd_uint_t lcd_put_u8str_P(PGM_P const ptpl, const int8_t ind, const char * const cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
+  dwin_string.set(ptpl, ind, cstr, fstr);
   dwin_string.truncate(maxlen);
-  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
-  lcd_advance_cursor(dwin_string.length());
-  return dwin_string.length();
+  DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
+  lcd_advance_cursor(dwin_string.length);
+  return dwin_string.length;
 }
 
 #if ENABLED(DEBUG_LCDPRINT)
diff --git a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
index d124c529464..f01a2beddf4 100644
--- a/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
+++ b/Marlin/src/lcd/e3v2/marlinui/ui_common.cpp
@@ -110,7 +110,7 @@ void MarlinUI::clear_lcd() {
       #define VERSION_Y   84
     #endif
 
-    DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length() * 10) / 2, VERSION_Y, S(dwin_string.string()));
+    DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length * 10) / 2, VERSION_Y, S(dwin_string.string()));
     TERN_(SHOW_CUSTOM_BOOTSCREEN, safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT));
     clear_lcd();
 
@@ -127,7 +127,7 @@ void MarlinUI::clear_lcd() {
       DWIN_ICON_Show(BOOT_ICON, ICON_MarlinURL,  INFO_CENTER - 100 / 2, 152);
       DWIN_ICON_Show(BOOT_ICON, ICON_Copyright,  INFO_CENTER - 126 / 2, 200);
     #endif
-    DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length() * 10) / 2, VERSION_Y, S(dwin_string.string()));
+    DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length * 10) / 2, VERSION_Y, S(dwin_string.string()));
     DWIN_UpdateLCD();
   }
 
@@ -284,7 +284,7 @@ void MarlinUI::draw_status_message(const bool blink) {
       else
         dwin_string.add(PSTR("    "));
 
-      lcd_moveto(LCD_WIDTH - dwin_string.length(), row);
+      lcd_moveto(LCD_WIDTH - dwin_string.length, row);
       lcd_put_dwin_string();
     }
 
@@ -311,7 +311,7 @@ void MarlinUI::draw_status_message(const bool blink) {
 
   // Draw a static line of text in the same idiom as a menu item
 
-  void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
+  void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
     // Call mark_as_selected to draw a bigger selection box
     // and draw the text without a background
     if (mark_as_selected(row, (bool)(style & SS_INVERT), true)) {
@@ -320,15 +320,15 @@ void MarlinUI::draw_status_message(const bool blink) {
       dwin_font.fg = Color_White;
 
       dwin_string.set();
-      const int8_t plen = fstr ? utf8_strlen(fstr) : 0,
+      const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
                    vlen = vstr ? utf8_strlen(vstr) : 0;
       if (style & SS_CENTER) {
         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2;
         while (--pad) dwin_string.add(' ');
       }
 
-      if (plen) dwin_string.add((uint8_t*)FTOP(fstr), itemIndex, (uint8_t*)FTOP(itemString));
-      if (vlen) dwin_string.add((uint8_t*)vstr);
+      if (plen) dwin_string.add(ftpl, itemIndex, itemStringC, itemStringF);
+      if (vlen) dwin_string.add(vstr);
       if (style & SS_CENTER) {
         int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2;
         while (--pad) dwin_string.add(' ');
@@ -340,15 +340,15 @@ void MarlinUI::draw_status_message(const bool blink) {
   }
 
   // Draw a generic menu item
-  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char, const char post_char) {
+  void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
     if (mark_as_selected(row, sel)) {
       ui.set_font(DWIN_FONT_MENU);
       dwin_font.solid = false;
       dwin_font.fg = Color_White;
 
-      dwin_string.set(fstr, itemIndex, FTOP(itemString));
+      dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF);
 
-      pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length();
+      pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length;
       while (--n > 1) dwin_string.add(' ');
 
       dwin_string.add(post_char);
@@ -361,7 +361,7 @@ void MarlinUI::draw_status_message(const bool blink) {
   //
   // Draw a menu item with an editable value
   //
-  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
+  void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
     if (mark_as_selected(row, sel)) {
       ui.set_font(DWIN_FONT_MENU);
       dwin_font.solid = false;
@@ -369,7 +369,7 @@ void MarlinUI::draw_status_message(const bool blink) {
 
       const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(S(inStr)));
 
-      dwin_string.set(fstr, itemIndex, FTOP(itemString));
+      dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF);
       if (vallen) dwin_string.add(':');
 
       lcd_moveto(1, row);
@@ -392,8 +392,7 @@ void MarlinUI::draw_status_message(const bool blink) {
 
     const dwin_coord_t labellen = utf8_strlen(fstr), vallen = utf8_strlen(value);
 
-    dwin_string.set();
-    dwin_string.add((uint8_t*)FTOP(fstr), itemIndex);
+    dwin_string.set(FTOP(fstr), itemIndex);
     if (vallen) dwin_string.add(':');  // If a value is included, add a colon
 
     // Assume the label is alpha-numeric (with a descender)
@@ -406,8 +405,7 @@ void MarlinUI::draw_status_message(const bool blink) {
 
     // If a value is included, print the value in larger text below the label
     if (vallen) {
-      dwin_string.set();
-      dwin_string.add(value);
+      dwin_string.set(value);
 
       const dwin_coord_t by = (row * MENU_LINE_HEIGHT) + MENU_FONT_HEIGHT + EXTRA_ROW_HEIGHT / 2;
       DWIN_Draw_String(true, font16x32, Color_Yellow, Color_Bg_Black, (LCD_PIXEL_WIDTH - vallen * 16) / 2, by, S(dwin_string.string()));
@@ -464,8 +462,8 @@ void MarlinUI::draw_status_message(const bool blink) {
           maxlen -= 2;
         }
 
-        dwin_string.add((uint8_t*)ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
-        uint8_t n = maxlen - dwin_string.length();
+        dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
+        uint8_t n = maxlen - dwin_string.length;
         while (n > 0) { dwin_string.add(' '); --n; }
         lcd_moveto(1, row);
         lcd_put_dwin_string();
@@ -548,7 +546,7 @@ void MarlinUI::draw_status_message(const bool blink) {
       dwin_string.add(i8tostr3rj(y_plot));
       dwin_string.add(")");
       lcd_moveto(
-        TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()),
+        TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length),
         TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 2, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 1)
       );
       lcd_put_dwin_string();
@@ -560,7 +558,7 @@ void MarlinUI::draw_status_message(const bool blink) {
       else
         dwin_string.add(PSTR(" -----"));
       lcd_moveto(
-        TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()),
+        TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length),
         TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 1, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 2)
       );
       lcd_put_dwin_string();
diff --git a/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp b/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp
index ba6814a57a1..810eaf361a0 100644
--- a/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp
+++ b/Marlin/src/lcd/e3v2/marlinui/ui_status_480x272.cpp
@@ -72,8 +72,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
 
     uint8_t vallen = utf8_strlen(value);
     if (!ui.did_first_redraw) {
-      dwin_string.set();
-      dwin_string.add('X' + axis);
+      dwin_string.set('X' + axis);
       DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x + (vallen * 14 - 14) / 2, y + 2, S(dwin_string.string()));
     }
 
@@ -96,8 +95,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
   #else // !DWIN_MARLINUI_PORTRAIT
 
     if (!ui.did_first_redraw || ui.old_is_printing != print_job_timer.isRunning()) {
-      dwin_string.set();
-      dwin_string.add('X' + axis);
+      dwin_string.set('X' + axis);
       DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x, y, S(dwin_string.string()));
     }
 
@@ -391,7 +389,7 @@ void MarlinUI::draw_status_screen() {
     time.toDigital(buffer);
     dwin_string.add(prefix);
     dwin_string.add(buffer);
-    DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, (LCD_PIXEL_WIDTH - ((dwin_string.length() + 1) * 14)), 290, S(dwin_string.string()));
+    DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, (LCD_PIXEL_WIDTH - ((dwin_string.length + 1) * 14)), 290, S(dwin_string.string()));
 
   #else
 
@@ -454,7 +452,7 @@ void MarlinUI::draw_status_screen() {
         dwin_string.add(PSTR("%"));
         DWIN_Draw_String(
           false, font16x32, Percent_Color, Color_Bg_Black,
-          pb_left + (pb_width - dwin_string.length() * 16) / 2,
+          pb_left + (pb_width - dwin_string.length * 16) / 2,
           pb_top + (pb_height - 32) / 2,
           S(dwin_string.string())
         );
diff --git a/Marlin/src/lcd/e3v2/proui/dwin.cpp b/Marlin/src/lcd/e3v2/proui/dwin.cpp
index 122136c1a08..709ed05fed7 100644
--- a/Marlin/src/lcd/e3v2/proui/dwin.cpp
+++ b/Marlin/src/lcd/e3v2/proui/dwin.cpp
@@ -3437,14 +3437,14 @@ void Draw_MaxSpeed_Menu() {
   if (!MaxSpeedMenu) MaxSpeedMenu = new MenuClass();
   if (CurrentMenu != MaxSpeedMenu) {
     CurrentMenu = MaxSpeedMenu;
-    SetMenuTitle({1, 16, 28, 13}, GET_TEXT_F(MSG_MAXSPEED));
+    SetMenuTitle({1, 16, 28, 13}, GET_TEXT_F(MSG_MAX_SPEED));
     MenuItemsPrepare(5);
     BACK_ITEM(Draw_Motion_Menu);
-    EDIT_ITEM_F(ICON_MaxSpeedX, MSG_MAXSPEED_X, onDrawMaxSpeedX, SetMaxSpeedX, &planner.settings.max_feedrate_mm_s[X_AXIS]);
-    EDIT_ITEM_F(ICON_MaxSpeedY, MSG_MAXSPEED_Y, onDrawMaxSpeedY, SetMaxSpeedY, &planner.settings.max_feedrate_mm_s[Y_AXIS]);
-    EDIT_ITEM_F(ICON_MaxSpeedZ, MSG_MAXSPEED_Z, onDrawMaxSpeedZ, SetMaxSpeedZ, &planner.settings.max_feedrate_mm_s[Z_AXIS]);
+    EDIT_ITEM_F(ICON_MaxSpeedX, MSG_VMAX_A, onDrawMaxSpeedX, SetMaxSpeedX, &planner.settings.max_feedrate_mm_s[X_AXIS]);
+    EDIT_ITEM_F(ICON_MaxSpeedY, MSG_VMAX_B, onDrawMaxSpeedY, SetMaxSpeedY, &planner.settings.max_feedrate_mm_s[Y_AXIS]);
+    EDIT_ITEM_F(ICON_MaxSpeedZ, MSG_VMAX_C, onDrawMaxSpeedZ, SetMaxSpeedZ, &planner.settings.max_feedrate_mm_s[Z_AXIS]);
     #if HAS_HOTEND
-      EDIT_ITEM_F(ICON_MaxSpeedE, MSG_MAXSPEED_E, onDrawMaxSpeedE, SetMaxSpeedE, &planner.settings.max_feedrate_mm_s[E_AXIS]);
+      EDIT_ITEM_F(ICON_MaxSpeedE, MSG_VMAX_E, onDrawMaxSpeedE, SetMaxSpeedE, &planner.settings.max_feedrate_mm_s[E_AXIS]);
     #endif
   }
   CurrentMenu->draw();
diff --git a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp
index f2cefe0cb74..6cdafc8a935 100644
--- a/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp
+++ b/Marlin/src/lcd/e3v2/proui/dwin_lcd.cpp
@@ -147,7 +147,7 @@ void DWIN_SRAMToPic(uint8_t picID) {
 
 //--------------------------Test area -------------------------
 
-//void DWIN_ReadSRAM(uint16_t addr, uint8_t length, const char * const data) {
+//void DWIN_ReadSRAM(uint16_t addr, const uint8_t length, const char * const data) {
 //  size_t i = 0;
 //  DWIN_Byte(i, 0x32);
 //  DWIN_Byte(i, 0x5A);  // 0x5A Read from SRAM - 0xA5 Read from Flash
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.cpp
index e9df264c1dd..e3b95c4cd49 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.cpp
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/bioprinter/advanced_settings.cpp
@@ -54,7 +54,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
 
 
       .tag(7) .button(BTN_POS(2,1), BTN_SIZE(1,1), GET_TEXT_F(MSG_STEPS_PER_MM))
-      .tag(8) .button(BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_VELOCITY))
+      .tag(8) .button(BTN_POS(2,2), BTN_SIZE(1,1), GET_TEXT_F(MSG_MAX_SPEED))
       .tag(9) .button(BTN_POS(2,3), BTN_SIZE(1,1), GET_TEXT_F(MSG_ACCELERATION))
       .tag(10) .button(BTN_POS(2,4), BTN_SIZE(1,1), GET_TEXT_F(TERN(HAS_JUNCTION_DEVIATION, MSG_JUNCTION_DEVIATION, MSG_JERK)))
                .enabled(ENABLED(BACKLASH_GCODE))
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.cpp
index 888f2c2cdd2..00cdf76331d 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.cpp
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/cocoa_press/advanced_settings_menu.cpp
@@ -59,7 +59,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
       .tag(3) .button(TMC_CURRENT_POS,        GET_TEXT_F(MSG_TMC_CURRENT))
               .enabled(ENABLED(LIN_ADVANCE))
       .tag(4) .button(LIN_ADVANCE_POS,         GET_TEXT_F(MSG_LINEAR_ADVANCE))
-      .tag(5) .button(VELOCITY_POS,           GET_TEXT_F(MSG_VELOCITY))
+      .tag(5) .button(VELOCITY_POS,           GET_TEXT_F(MSG_MAX_SPEED))
       .tag(6) .button(ACCELERATION_POS,       GET_TEXT_F(MSG_ACCELERATION))
       .tag(7) .button(JERK_POS,               GET_TEXT_F(TERN(HAS_JUNCTION_DEVIATION, MSG_JUNCTION_DEVIATION, MSG_JERK)))
       .tag(8) .button(ENDSTOPS_POS,           GET_TEXT_F(MSG_LCD_ENDSTOPS))
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.cpp
index 8e0a01e1c8a..8753b44e709 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.cpp
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/advanced_settings_menu.cpp
@@ -105,7 +105,7 @@ void AdvancedSettingsMenu::onRedraw(draw_mode_t what) {
       .tag(15).button(DISPLAY_POS,            GET_TEXT_F(MSG_DISPLAY_MENU))
       .tag(9) .button(INTERFACE_POS,          GET_TEXT_F(MSG_INTERFACE))
       .tag(10).button(RESTORE_DEFAULTS_POS,   GET_TEXT_F(MSG_RESTORE_DEFAULTS))
-      .tag(5) .button(VELOCITY_POS,           GET_TEXT_F(MSG_VELOCITY))
+      .tag(5) .button(VELOCITY_POS,           GET_TEXT_F(MSG_MAX_SPEED))
       .tag(6) .button(ACCELERATION_POS,       GET_TEXT_F(MSG_ACCELERATION))
       .tag(7) .button(JERK_POS,               GET_TEXT_F(TERN(HAS_JUNCTION_DEVIATION, MSG_JUNCTION_DEVIATION, MSG_JERK)))
       .enabled(ENABLED(BACKLASH_GCODE))
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.cpp b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.cpp
index 01112762112..e7fc23ab487 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.cpp
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/generic/max_velocity_screen.cpp
@@ -34,7 +34,7 @@ void MaxVelocityScreen::onRedraw(draw_mode_t what) {
   widgets_t w(what);
   w.precision(0);
   w.units(GET_TEXT_F(MSG_UNITS_MM_S));
-  w.heading(                        GET_TEXT_F(MSG_VELOCITY));
+  w.heading(                        GET_TEXT_F(MSG_MAX_SPEED));
   w.color(x_axis)    .adjuster(  2, GET_TEXT_F(MSG_VMAX_X), getAxisMaxFeedrate_mm_s(X) );
   w.color(y_axis)    .adjuster(  4, GET_TEXT_F(MSG_VMAX_Y), getAxisMaxFeedrate_mm_s(Y) );
   w.color(z_axis)    .adjuster(  6, GET_TEXT_F(MSG_VMAX_Z), getAxisMaxFeedrate_mm_s(Z) );
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language.h
index cbc05c5aa3b..8c123db6a1f 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language.h
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language.h
@@ -20,4 +20,6 @@
  ****************************************************************************/
 #pragma once
 
+#define LSTR PROGMEM Language_Str
+
 #include "language_en.h"
diff --git a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h
index 83e762430ce..5dbde8a5c35 100644
--- a/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h
+++ b/Marlin/src/lcd/extui/ftdi_eve_touch_ui/language/language_en.h
@@ -36,142 +36,142 @@
 #endif
 
 namespace Language_en {
-  PROGMEM Language_Str MSG_BUTTON_OKAY              = u8"Okay";
-  PROGMEM Language_Str MSG_BUTTON_MENU              = u8"Menu";
-  PROGMEM Language_Str MSG_BUTTON_MEDIA             = u8"Media";
-  PROGMEM Language_Str MSG_BUTTON_OPEN              = u8"Open";
-  PROGMEM Language_Str MSG_CLEAN_NOZZLE             = u8"Clean Nozzle";
-  PROGMEM Language_Str MSG_VMAX_X                   = u8"Vmax X";
-  PROGMEM Language_Str MSG_VMAX_Y                   = u8"Vmax Y";
-  PROGMEM Language_Str MSG_VMAX_Z                   = u8"Vmax Z";
-  PROGMEM Language_Str MSG_ACCEL_PRINTING           = u8"Printing";
-  PROGMEM Language_Str MSG_ACCEL_TRAVEL             = u8"Travel";
-  PROGMEM Language_Str MSG_ACCEL_RETRACT            = u8"Retraction";
-  PROGMEM Language_Str MSG_AMAX_X                   = u8"Amax X";
-  PROGMEM Language_Str MSG_AMAX_Y                   = u8"Amax Y";
-  PROGMEM Language_Str MSG_AMAX_Z                   = u8"Amax Z";
-  PROGMEM Language_Str MSG_AXIS_X                   = u8"X";
-  PROGMEM Language_Str MSG_AXIS_X2                  = u8"X2";
-  PROGMEM Language_Str MSG_AXIS_Y                   = u8"Y";
-  PROGMEM Language_Str MSG_AXIS_Y2                  = u8"Y2";
-  PROGMEM Language_Str MSG_AXIS_Z                   = u8"Z";
-  PROGMEM Language_Str MSG_AXIS_Z2                  = u8"Z2";
-  PROGMEM Language_Str MSG_AXIS_E                   = u8"E";
-  PROGMEM Language_Str MSG_AXIS_E1                  = u8"E1";
-  PROGMEM Language_Str MSG_AXIS_E2                  = u8"E2";
-  PROGMEM Language_Str MSG_AXIS_E3                  = u8"E3";
-  PROGMEM Language_Str MSG_AXIS_E4                  = u8"E4";
-  PROGMEM Language_Str MSG_AXIS_ALL                 = u8"All";
-  PROGMEM Language_Str MSG_HOME                     = u8"Home";
-  PROGMEM Language_Str MSG_PRINT_STARTING           = u8"Print starting";
-  PROGMEM Language_Str MSG_PRINT_FINISHED           = u8"Print finished";
-  PROGMEM Language_Str MSG_PRINT_ERROR              = u8"Print error";
-  PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_1      = u8"Color Touch Panel";
-  PROGMEM Language_Str MSG_ABOUT_TOUCH_PANEL_2      = WEBSITE_URL;
-  PROGMEM Language_Str MSG_LICENSE                  = u8"This program is free software: you can redistribute it and/or modify it under the terms of "
+  LSTR MSG_BUTTON_OKAY              = u8"Okay";
+  LSTR MSG_BUTTON_MENU              = u8"Menu";
+  LSTR MSG_BUTTON_MEDIA             = u8"Media";
+  LSTR MSG_BUTTON_OPEN              = u8"Open";
+  LSTR MSG_CLEAN_NOZZLE             = u8"Clean Nozzle";
+  LSTR MSG_VMAX_X                   = u8"Max X Speed";
+  LSTR MSG_VMAX_Y                   = u8"Max Y Speed";
+  LSTR MSG_VMAX_Z                   = u8"Max Z Speed";
+  LSTR MSG_ACCEL_PRINTING           = u8"Printing";
+  LSTR MSG_ACCEL_TRAVEL             = u8"Travel";
+  LSTR MSG_ACCEL_RETRACT            = u8"Retraction";
+  LSTR MSG_AMAX_X                   = u8"Max X Accel.";
+  LSTR MSG_AMAX_Y                   = u8"Max Y Accel.";
+  LSTR MSG_AMAX_Z                   = u8"Max Z Accel.";
+  LSTR MSG_AXIS_X                   = u8"X";
+  LSTR MSG_AXIS_X2                  = u8"X2";
+  LSTR MSG_AXIS_Y                   = u8"Y";
+  LSTR MSG_AXIS_Y2                  = u8"Y2";
+  LSTR MSG_AXIS_Z                   = u8"Z";
+  LSTR MSG_AXIS_Z2                  = u8"Z2";
+  LSTR MSG_AXIS_E                   = u8"E";
+  LSTR MSG_AXIS_E1                  = u8"E1";
+  LSTR MSG_AXIS_E2                  = u8"E2";
+  LSTR MSG_AXIS_E3                  = u8"E3";
+  LSTR MSG_AXIS_E4                  = u8"E4";
+  LSTR MSG_AXIS_ALL                 = u8"All";
+  LSTR MSG_HOME                     = u8"Home";
+  LSTR MSG_PRINT_STARTING           = u8"Print starting";
+  LSTR MSG_PRINT_FINISHED           = u8"Print finished";
+  LSTR MSG_PRINT_ERROR              = u8"Print error";
+  LSTR MSG_ABOUT_TOUCH_PANEL_1      = u8"Color Touch Panel";
+  LSTR MSG_ABOUT_TOUCH_PANEL_2      = WEBSITE_URL;
+  LSTR MSG_LICENSE                  = u8"This program is free software: you can redistribute it and/or modify it under the terms of "
                                                         "the GNU General Public License as published by the Free Software Foundation, either version 3 "
                                                         "of the License, or (at your option) any later version. To view a copy of the GNU General "
                                                         "Public License, go to the following location: https://www.gnu.org/licenses.";
-  PROGMEM Language_Str MSG_RUNOUT_1                 = u8"Runout 1";
-  PROGMEM Language_Str MSG_RUNOUT_2                 = u8"Runout 2";
-  PROGMEM Language_Str MSG_DISPLAY_MENU             = u8"Display";
-  PROGMEM Language_Str MSG_INTERFACE                = u8"Interface";
-  PROGMEM Language_Str MSG_MEASURE_AUTOMATICALLY    = u8"Measure automatically";
-  PROGMEM Language_Str MSG_H_OFFSET                 = u8"H Offset";
-  PROGMEM Language_Str MSG_V_OFFSET                 = u8"V Offset";
-  PROGMEM Language_Str MSG_TOUCH_SCREEN             = u8"Touch Screen";
-  PROGMEM Language_Str MSG_CALIBRATE                = u8"Calibrate";
-  PROGMEM Language_Str MSG_UNITS_MILLIAMP           = u8"mA";
-  PROGMEM Language_Str MSG_UNITS_MM                 = u8"mm";
-  PROGMEM Language_Str MSG_UNITS_MM_S               = u8"mm/s";
-  PROGMEM Language_Str MSG_UNITS_MM_S2              = u8"mm/s" SUPERSCRIPT_TWO;
-  PROGMEM Language_Str MSG_UNITS_STEP_MM            = u8"st/mm";
-  PROGMEM Language_Str MSG_UNITS_PERCENT            = u8"%";
-  PROGMEM Language_Str MSG_UNITS_C                  = DEGREE_SIGN u8"C";
-  PROGMEM Language_Str MSG_IDLE                     = u8"idle";
-  PROGMEM Language_Str MSG_SET_MAXIMUM              = u8"Set Maximum";
-  PROGMEM Language_Str MSG_PRINT_SPEED              = u8"Print Speed";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE           = u8"Linear Advance";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE_K         = u8"K";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE_K1        = u8"K E1";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE_K2        = u8"K E2";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE_K3        = u8"K E3";
-  PROGMEM Language_Str MSG_LINEAR_ADVANCE_K4        = u8"K E4";
-  PROGMEM Language_Str MSG_NUDGE_NOZZLE             = u8"Nudge Nozzle";
-  PROGMEM Language_Str MSG_ADJUST_BOTH_NOZZLES      = u8"Adjust Both Nozzles";
-  PROGMEM Language_Str MSG_SHOW_OFFSETS             = u8"Show Offsets";
-  PROGMEM Language_Str MSG_INCREMENT                = u8"Increment";
-  PROGMEM Language_Str MSG_ERASE_FLASH_WARNING      = u8"Are you sure? SPI flash will be erased.";
-  PROGMEM Language_Str MSG_ERASING                  = u8"Erasing...";
-  PROGMEM Language_Str MSG_ERASED                   = u8"SPI flash erased";
-  PROGMEM Language_Str MSG_CALIBRATION_WARNING      = u8"For best results, unload the filament and clean the hotend prior to starting calibration. Continue?";
-  PROGMEM Language_Str MSG_START_PRINT_CONFIRMATION = u8"Start printing %s?";
-  PROGMEM Language_Str MSG_ABORT_WARNING            = u8"Are you sure you want to cancel the print?";
-  PROGMEM Language_Str MSG_EXTRUDER_SELECTION       = u8"Extruder Selection";
-  PROGMEM Language_Str MSG_CURRENT_TEMPERATURE      = u8"Current Temp";
-  PROGMEM Language_Str MSG_REMOVAL_TEMPERATURE      = u8"Removal Temp";
-  PROGMEM Language_Str MSG_CAUTION                  = u8"Caution:";
-  PROGMEM Language_Str MSG_HOT                      = u8"Hot!";
-  PROGMEM Language_Str MSG_UNLOAD_FILAMENT          = u8"Unload/Retract";
-  PROGMEM Language_Str MSG_LOAD_FILAMENT            = u8"Load/Extrude";
-  PROGMEM Language_Str MSG_MOMENTARY                = u8"Momentary";
-  PROGMEM Language_Str MSG_CONTINUOUS               = u8"Continuous";
-  PROGMEM Language_Str MSG_PRINT_MENU               = u8"Print Menu";
-  PROGMEM Language_Str MSG_FINE_MOTION              = u8"Fine motion";
-  PROGMEM Language_Str MSG_ENABLE_MEDIA             = u8"Enable Media";
-  PROGMEM Language_Str MSG_INSERT_MEDIA             = u8"Insert Media...";
-  PROGMEM Language_Str MSG_LCD_BRIGHTNESS           = u8"LCD brightness";
-  PROGMEM Language_Str MSG_SOUND_VOLUME             = u8"Sound volume";
-  PROGMEM Language_Str MSG_SCREEN_LOCK              = u8"Screen lock";
-  PROGMEM Language_Str MSG_BOOT_SCREEN              = u8"Boot screen";
-  PROGMEM Language_Str MSG_SOUNDS                   = u8"Sounds";
-  PROGMEM Language_Str MSG_CLICK_SOUNDS             = u8"Click sounds";
-  PROGMEM Language_Str MSG_EEPROM_RESTORED          = u8"Settings restored from backup";
-  PROGMEM Language_Str MSG_EEPROM_RESET             = u8"Settings restored to default";
-  PROGMEM Language_Str MSG_EEPROM_SAVED             = u8"Settings saved!";
-  PROGMEM Language_Str MSG_EEPROM_SAVE_PROMPT       = u8"Settings applied. Save these settings for next power-on?";
-  PROGMEM Language_Str MSG_EEPROM_RESET_WARNING     = u8"Are you sure? Customizations will be lost.";
+  LSTR MSG_RUNOUT_1                 = u8"Runout 1";
+  LSTR MSG_RUNOUT_2                 = u8"Runout 2";
+  LSTR MSG_DISPLAY_MENU             = u8"Display";
+  LSTR MSG_INTERFACE                = u8"Interface";
+  LSTR MSG_MEASURE_AUTOMATICALLY    = u8"Measure automatically";
+  LSTR MSG_H_OFFSET                 = u8"H Offset";
+  LSTR MSG_V_OFFSET                 = u8"V Offset";
+  LSTR MSG_TOUCH_SCREEN             = u8"Touch Screen";
+  LSTR MSG_CALIBRATE                = u8"Calibrate";
+  LSTR MSG_UNITS_MILLIAMP           = u8"mA";
+  LSTR MSG_UNITS_MM                 = u8"mm";
+  LSTR MSG_UNITS_MM_S               = u8"mm/s";
+  LSTR MSG_UNITS_MM_S2              = u8"mm/s" SUPERSCRIPT_TWO;
+  LSTR MSG_UNITS_STEP_MM            = u8"st/mm";
+  LSTR MSG_UNITS_PERCENT            = u8"%";
+  LSTR MSG_UNITS_C                  = DEGREE_SIGN u8"C";
+  LSTR MSG_IDLE                     = u8"idle";
+  LSTR MSG_SET_MAXIMUM              = u8"Set Maximum";
+  LSTR MSG_PRINT_SPEED              = u8"Print Speed";
+  LSTR MSG_LINEAR_ADVANCE           = u8"Linear Advance";
+  LSTR MSG_LINEAR_ADVANCE_K         = u8"K";
+  LSTR MSG_LINEAR_ADVANCE_K1        = u8"K E1";
+  LSTR MSG_LINEAR_ADVANCE_K2        = u8"K E2";
+  LSTR MSG_LINEAR_ADVANCE_K3        = u8"K E3";
+  LSTR MSG_LINEAR_ADVANCE_K4        = u8"K E4";
+  LSTR MSG_NUDGE_NOZZLE             = u8"Nudge Nozzle";
+  LSTR MSG_ADJUST_BOTH_NOZZLES      = u8"Adjust Both Nozzles";
+  LSTR MSG_SHOW_OFFSETS             = u8"Show Offsets";
+  LSTR MSG_INCREMENT                = u8"Increment";
+  LSTR MSG_ERASE_FLASH_WARNING      = u8"Are you sure? SPI flash will be erased.";
+  LSTR MSG_ERASING                  = u8"Erasing...";
+  LSTR MSG_ERASED                   = u8"SPI flash erased";
+  LSTR MSG_CALIBRATION_WARNING      = u8"For best results, unload the filament and clean the hotend prior to starting calibration. Continue?";
+  LSTR MSG_START_PRINT_CONFIRMATION = u8"Start printing %s?";
+  LSTR MSG_ABORT_WARNING            = u8"Are you sure you want to cancel the print?";
+  LSTR MSG_EXTRUDER_SELECTION       = u8"Extruder Selection";
+  LSTR MSG_CURRENT_TEMPERATURE      = u8"Current Temp";
+  LSTR MSG_REMOVAL_TEMPERATURE      = u8"Removal Temp";
+  LSTR MSG_CAUTION                  = u8"Caution:";
+  LSTR MSG_HOT                      = u8"Hot!";
+  LSTR MSG_UNLOAD_FILAMENT          = u8"Unload/Retract";
+  LSTR MSG_LOAD_FILAMENT            = u8"Load/Extrude";
+  LSTR MSG_MOMENTARY                = u8"Momentary";
+  LSTR MSG_CONTINUOUS               = u8"Continuous";
+  LSTR MSG_PRINT_MENU               = u8"Print Menu";
+  LSTR MSG_FINE_MOTION              = u8"Fine motion";
+  LSTR MSG_ENABLE_MEDIA             = u8"Enable Media";
+  LSTR MSG_INSERT_MEDIA             = u8"Insert Media...";
+  LSTR MSG_LCD_BRIGHTNESS           = u8"LCD brightness";
+  LSTR MSG_SOUND_VOLUME             = u8"Sound volume";
+  LSTR MSG_SCREEN_LOCK              = u8"Screen lock";
+  LSTR MSG_BOOT_SCREEN              = u8"Boot screen";
+  LSTR MSG_SOUNDS                   = u8"Sounds";
+  LSTR MSG_CLICK_SOUNDS             = u8"Click sounds";
+  LSTR MSG_EEPROM_RESTORED          = u8"Settings restored from backup";
+  LSTR MSG_EEPROM_RESET             = u8"Settings restored to default";
+  LSTR MSG_EEPROM_SAVED             = u8"Settings saved!";
+  LSTR MSG_EEPROM_SAVE_PROMPT       = u8"Settings applied. Save these settings for next power-on?";
+  LSTR MSG_EEPROM_RESET_WARNING     = u8"Are you sure? Customizations will be lost.";
 
-  PROGMEM Language_Str MSG_PASSCODE_REJECTED        = u8"Wrong passcode!";
-  PROGMEM Language_Str MSG_PASSCODE_ACCEPTED        = u8"Passcode accepted!";
-  PROGMEM Language_Str MSG_PASSCODE_SELECT          = u8"Select Passcode:";
-  PROGMEM Language_Str MSG_PASSCODE_REQUEST         = u8"Enter Passcode:";
+  LSTR MSG_PASSCODE_REJECTED        = u8"Wrong passcode!";
+  LSTR MSG_PASSCODE_ACCEPTED        = u8"Passcode accepted!";
+  LSTR MSG_PASSCODE_SELECT          = u8"Select Passcode:";
+  LSTR MSG_PASSCODE_REQUEST         = u8"Enter Passcode:";
 
-  PROGMEM Language_Str MSG_TOUCH_CALIBRATION_START  = u8"Release to begin screen calibration";
-  PROGMEM Language_Str MSG_TOUCH_CALIBRATION_PROMPT = u8"Touch the dots to calibrate";
-  PROGMEM Language_Str MSG_BED_MAPPING_DONE         = u8"Bed mapping finished";
-  PROGMEM Language_Str MSG_BED_MAPPING_INCOMPLETE   = u8"Not all points probed";
-  PROGMEM Language_Str MSG_LEVELING                 = u8"Leveling";
-  PROGMEM Language_Str MSG_AXIS_LEVELING            = u8"Axis Leveling";
-  PROGMEM Language_Str MSG_PROBE_BED                = u8"Probe Mesh";
-  PROGMEM Language_Str MSG_PRINT_TEST               = u8"Print Test (PLA)";
-  PROGMEM Language_Str MSG_MOVE_Z_TO_TOP            = u8"Raise Z to Top";
+  LSTR MSG_TOUCH_CALIBRATION_START  = u8"Release to begin screen calibration";
+  LSTR MSG_TOUCH_CALIBRATION_PROMPT = u8"Touch the dots to calibrate";
+  LSTR MSG_BED_MAPPING_DONE         = u8"Bed mapping finished";
+  LSTR MSG_BED_MAPPING_INCOMPLETE   = u8"Not all points probed";
+  LSTR MSG_LEVELING                 = u8"Leveling";
+  LSTR MSG_AXIS_LEVELING            = u8"Axis Leveling";
+  LSTR MSG_PROBE_BED                = u8"Probe Mesh";
+  LSTR MSG_PRINT_TEST               = u8"Print Test (PLA)";
+  LSTR MSG_MOVE_Z_TO_TOP            = u8"Raise Z to Top";
 
   #if ENABLED(TOUCH_UI_LULZBOT_BIO)
-    PROGMEM Language_Str MSG_MOVE_TO_HOME           = u8"Move to Home";
-    PROGMEM Language_Str MSG_RAISE_PLUNGER          = u8"Raise Plunger";
-    PROGMEM Language_Str MSG_RELEASE_XY_AXIS        = u8"Release X and Y Axis";
-    PROGMEM Language_Str MSG_BED_TEMPERATURE        = u8"Bed Temperature";
-    PROGMEM Language_Str MSG_HOME_XYZ_WARNING       = u8"About to move to home position. Ensure the top and the bed of the printer are clear.\n\nContinue?";
-    PROGMEM Language_Str MSG_HOME_E_WARNING         = u8"About to re-home plunger and auto-level. Remove syringe prior to proceeding.\n\nContinue?";
+    LSTR MSG_MOVE_TO_HOME           = u8"Move to Home";
+    LSTR MSG_RAISE_PLUNGER          = u8"Raise Plunger";
+    LSTR MSG_RELEASE_XY_AXIS        = u8"Release X and Y Axis";
+    LSTR MSG_BED_TEMPERATURE        = u8"Bed Temperature";
+    LSTR MSG_HOME_XYZ_WARNING       = u8"About to move to home position. Ensure the top and the bed of the printer are clear.\n\nContinue?";
+    LSTR MSG_HOME_E_WARNING         = u8"About to re-home plunger and auto-level. Remove syringe prior to proceeding.\n\nContinue?";
   #endif
 
   #ifdef TOUCH_UI_COCOA_PRESS
-    PROGMEM Language_Str MSG_BODY                   = u8"Body";
-    PROGMEM Language_Str MSG_SELECT_CHOCOLATE_TYPE  = u8"Select Chocolate Type";
-    PROGMEM Language_Str MSG_EXTERNAL               = u8"External";
-    PROGMEM Language_Str MSG_CHOCOLATE              = u8"Chocolate";
-    PROGMEM Language_Str MSG_UNLOAD_CARTRIDGE       = u8"Unload Cartridge";
-    PROGMEM Language_Str MSG_LOAD_UNLOAD            = u8"Load/Unload";
-    PROGMEM Language_Str MSG_FULL_LOAD              = u8"Full Load";
-    PROGMEM Language_Str MSG_FULL_UNLOAD            = u8"Full Unload";
-    PROGMEM Language_Str MSG_PREHEAT_CHOCOLATE      = u8"Preheat Chocolate";
-    PROGMEM Language_Str MSG_PREHEAT_FINISHED       = u8"Preheat finished";
-    PROGMEM Language_Str MSG_PREHEAT                = u8"Preheat";
-    PROGMEM Language_Str MSG_BUTTON_PAUSE           = u8"Pause";
-    PROGMEM Language_Str MSG_BUTTON_RESUME          = u8"Resume";
-    PROGMEM Language_Str MSG_ELAPSED_PRINT          = u8"Elapsed Print";
-    PROGMEM Language_Str MSG_XYZ_MOVE               = u8"XYZ Move";
-    PROGMEM Language_Str MSG_E_MOVE                 = u8"Extrusion Move";
+    LSTR MSG_BODY                   = u8"Body";
+    LSTR MSG_SELECT_CHOCOLATE_TYPE  = u8"Select Chocolate Type";
+    LSTR MSG_EXTERNAL               = u8"External";
+    LSTR MSG_CHOCOLATE              = u8"Chocolate";
+    LSTR MSG_UNLOAD_CARTRIDGE       = u8"Unload Cartridge";
+    LSTR MSG_LOAD_UNLOAD            = u8"Load/Unload";
+    LSTR MSG_FULL_LOAD              = u8"Full Load";
+    LSTR MSG_FULL_UNLOAD            = u8"Full Unload";
+    LSTR MSG_PREHEAT_CHOCOLATE      = u8"Preheat Chocolate";
+    LSTR MSG_PREHEAT_FINISHED       = u8"Preheat finished";
+    LSTR MSG_PREHEAT                = u8"Preheat";
+    LSTR MSG_BUTTON_PAUSE           = u8"Pause";
+    LSTR MSG_BUTTON_RESUME          = u8"Resume";
+    LSTR MSG_ELAPSED_PRINT          = u8"Elapsed Print";
+    LSTR MSG_XYZ_MOVE               = u8"XYZ Move";
+    LSTR MSG_E_MOVE                 = u8"Extrusion Move";
   #endif
 }; // namespace Language_en
diff --git a/Marlin/src/lcd/fontutils.cpp b/Marlin/src/lcd/fontutils.cpp
index 50b671ea33a..a97e63ac4d3 100644
--- a/Marlin/src/lcd/fontutils.cpp
+++ b/Marlin/src/lcd/fontutils.cpp
@@ -40,13 +40,8 @@
 
 #include "fontutils.h"
 
-uint8_t read_byte_ram(uint8_t * str) {
-  return *str;
-}
-
-uint8_t read_byte_rom(uint8_t * str) {
-  return pgm_read_byte(str);
-}
+uint8_t read_byte_ram(const uint8_t *str) { return *str; }
+uint8_t read_byte_rom(const uint8_t *str) { return pgm_read_byte(str); }
 
 /**
  * @brief Using binary search to find the position by data_pin
@@ -104,9 +99,9 @@ static inline bool utf8_is_start_byte_of_char(const uint8_t b) {
 
 /* This function gets the character at the pstart position, interpreting UTF8 multibyte sequences
    and returns the pointer to the next character */
-uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
+const uint8_t* get_utf8_value_cb(const uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
   uint32_t val = 0;
-  uint8_t *p = pstart;
+  const uint8_t *p = pstart;
 
   #define NEXT_6_BITS() do{ val <<= 6; p++; valcur = cb_read_byte(p); val |= (valcur & 0x3F); }while(0)
 
diff --git a/Marlin/src/lcd/fontutils.h b/Marlin/src/lcd/fontutils.h
index 21aee1e9391..e01962d7ad8 100644
--- a/Marlin/src/lcd/fontutils.h
+++ b/Marlin/src/lcd/fontutils.h
@@ -38,10 +38,10 @@
 #include "../core/macros.h"
 
 // read a byte from ROM or RAM
-typedef uint8_t (*read_byte_cb_t)(uint8_t * str);
+typedef uint8_t (*read_byte_cb_t)(const uint8_t * str);
 
-uint8_t read_byte_ram(uint8_t * str);
-uint8_t read_byte_rom(uint8_t * str);
+uint8_t read_byte_ram(const uint8_t *str);
+uint8_t read_byte_rom(const uint8_t *str);
 
 // there's overflow of the wchar_t due to the 2-byte size in Arduino
 // sizeof(wchar_t)=2; sizeof(size_t)=2; sizeof(uint32_t)=4;
@@ -58,7 +58,11 @@ typedef int (* pf_bsearch_cb_comp_t)(void *userdata, size_t idx, void * data_pin
 int pf_bsearch_r(void *userdata, size_t num_data, pf_bsearch_cb_comp_t cb_comp, void *data_pinpoint, size_t *ret_idx);
 
 /* Get the character, decoding multibyte UTF8 characters and returning a pointer to the start of the next UTF8 character */
-uint8_t* get_utf8_value_cb(uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
+const uint8_t* get_utf8_value_cb(const uint8_t *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval);
+
+inline const char* get_utf8_value_cb(const char *pstart, read_byte_cb_t cb_read_byte, wchar_t *pval) {
+  return (const char *)get_utf8_value_cb((const uint8_t *)pstart, cb_read_byte, pval);
+}
 
 /* Returns length of string in CHARACTERS, NOT BYTES */
 uint8_t utf8_strlen(const char *pstart);
diff --git a/Marlin/src/lcd/language/language_an.h b/Marlin/src/lcd/language/language_an.h
index c5a7e1877ec..98f3d4ed97e 100644
--- a/Marlin/src/lcd/language/language_an.h
+++ b/Marlin/src/lcd/language/language_an.h
@@ -85,7 +85,7 @@ namespace Language_an {
   LSTR MSG_MOVE_Z                         = _UxGT("Mover Z");
   LSTR MSG_MOVE_E                         = _UxGT("Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrusor *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mover 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mover 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mover 10mm");
@@ -109,10 +109,8 @@ namespace Language_an {
   LSTR MSG_AMAX_A                         = _UxGT("Acel. max ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Acel. max ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Acel. max ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Acel. max ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Acel. max ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Acel. max ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Acel. max ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Acel. max @");
+  LSTR MSG_AMAX_E                         = _UxGT("Acel. max E");
   LSTR MSG_AMAX_EN                        = _UxGT("Acel. max *");
   LSTR MSG_A_RETRACT                      = _UxGT("Acel. retrac.");
   LSTR MSG_A_TRAVEL                       = _UxGT("Acel. Viaje");
@@ -120,9 +118,7 @@ namespace Language_an {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" trangos/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" trangos/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" trangos/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" trangos/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" trangos/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" trangos/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ trangos/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E trangos/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* trangos/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -168,6 +164,7 @@ namespace Language_an {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Micropaso X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Micropaso Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Micropaso Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Micropaso @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Cancelado - Endstop");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Error: en calentar");
   LSTR MSG_ERR_REDUNDANT_TEMP             = _UxGT("Error: temperatura");
diff --git a/Marlin/src/lcd/language/language_bg.h b/Marlin/src/lcd/language/language_bg.h
index 95ca4ce1bfc..2596d62564e 100644
--- a/Marlin/src/lcd/language/language_bg.h
+++ b/Marlin/src/lcd/language/language_bg.h
@@ -74,7 +74,7 @@ namespace Language_bg {
   LSTR MSG_MOVE_Z                         = _UxGT("Движение по Z");
   LSTR MSG_MOVE_E                         = _UxGT("Екструдер");
   LSTR MSG_MOVE_EN                        = _UxGT("Екструдер *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Премести с %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Премести с $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Премести с 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Премести с 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Премести с 10mm");
@@ -101,9 +101,7 @@ namespace Language_bg {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" стъпки/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" стъпки/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" стъпки/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" стъпки/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" стъпки/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" стъпки/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ стъпки/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E стъпки/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* стъпки/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Температура");
@@ -148,6 +146,7 @@ namespace Language_bg {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Министъпка X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Министъпка Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Министъпка Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Министъпка @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Стоп Кр.Изключватели");
   LSTR MSG_DELTA_CALIBRATE                = _UxGT("Делта Калибровка");
   LSTR MSG_DELTA_CALIBRATE_X              = _UxGT("Калибровка X");
diff --git a/Marlin/src/lcd/language/language_ca.h b/Marlin/src/lcd/language/language_ca.h
index 582c27b1ae6..fd46bcc28fc 100644
--- a/Marlin/src/lcd/language/language_ca.h
+++ b/Marlin/src/lcd/language/language_ca.h
@@ -85,7 +85,7 @@ namespace Language_ca {
   LSTR MSG_MOVE_Z                         = _UxGT("Mou Z");
   LSTR MSG_MOVE_E                         = _UxGT("Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrusor *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mou %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mou $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mou 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mou 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mou 10mm");
@@ -107,11 +107,9 @@ namespace Language_ca {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" passos/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" passos/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" passos/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" passos/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" passos/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" passos/mm");
-  LSTR MSG_E_STEPS                        = _UxGT("Epassos/mm");
-  LSTR MSG_EN_STEPS                       = _UxGT("*passos/mm");
+  LSTR MSG_E_STEPS                        = _UxGT("@ passos/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("E passos/mm");
+  LSTR MSG_EN_STEPS                       = _UxGT("* passos/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
   LSTR MSG_MOTION                         = _UxGT("Moviment");
   LSTR MSG_FILAMENT                       = _UxGT("Filament");
@@ -156,6 +154,7 @@ namespace Language_ca {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Micropas X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Micropas Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Micropas Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Micropas @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Cancel. Endstop");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Error al escalfar");
   LSTR MSG_ERR_REDUNDANT_TEMP             = _UxGT("Err: TEMP REDUNDANT");
diff --git a/Marlin/src/lcd/language/language_cz.h b/Marlin/src/lcd/language/language_cz.h
index 76469c5fe5a..d78b43f9a9e 100644
--- a/Marlin/src/lcd/language/language_cz.h
+++ b/Marlin/src/lcd/language/language_cz.h
@@ -235,7 +235,7 @@ namespace Language_cz {
   LSTR MSG_MOVE_E                         = _UxGT("Extrudér");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrudér *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hotend je studený");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Posunout o %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Posunout o $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Posunout o 0,1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Posunout o 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Posunout o 10mm");
@@ -269,19 +269,15 @@ namespace Language_cz {
   LSTR MSG_VA_JERK                        = _UxGT("Max ") STR_A _UxGT(" Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("Max ") STR_B _UxGT(" Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("Max ") STR_C _UxGT(" Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("Max ") STR_I _UxGT(" Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("Max ") STR_J _UxGT(" Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("Max ") STR_K _UxGT(" Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("Max @ Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Max E Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Odchylka spoje");
-  LSTR MSG_VELOCITY                       = _UxGT("Rychlost");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Rychlost");
   LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Rychlost");
   LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Rychlost");
   LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Rychlost");
-  LSTR MSG_VMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Rychlost");
-  LSTR MSG_VMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Rychlost");
-  LSTR MSG_VMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Rychlost");
-  LSTR MSG_VMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Rychlost");
+  LSTR MSG_VMAX_N                         = _UxGT("Max @ Rychlost");
+  LSTR MSG_VMAX_E                         = _UxGT("Max E Rychlost");
   LSTR MSG_VMAX_EN                        = _UxGT("Max * Rychlost");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VTrav Min");
@@ -289,10 +285,8 @@ namespace Language_cz {
   LSTR MSG_AMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Akcel");
   LSTR MSG_AMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Akcel");
   LSTR MSG_AMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Akcel");
-  LSTR MSG_AMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Akcel");
-  LSTR MSG_AMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Akcel");
-  LSTR MSG_AMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Akcel");
-  LSTR MSG_AMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Akcel");
+  LSTR MSG_AMAX_N                         = _UxGT("Max @ Akcel");
+  LSTR MSG_AMAX_E                         = _UxGT("Max E Akcel");
   LSTR MSG_AMAX_EN                        = _UxGT("Max * Akcel");
   LSTR MSG_A_RETRACT                      = _UxGT("A-retrakt");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-přejezd");
@@ -300,9 +294,7 @@ namespace Language_cz {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" kroků/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" kroků/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" kroků/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" kroků/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" kroků/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" kroků/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ kroků/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E kroků/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* kroků/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Teplota");
@@ -407,6 +399,7 @@ namespace Language_cz {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Celkem");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop abort");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Chyba zahřívání");
@@ -482,13 +475,7 @@ namespace Language_cz {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Teplota max");
   LSTR MSG_INFO_PSU                       = _UxGT("Nap. zdroj");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Buzení motorů");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Motor %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Motor %");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC uložit EEPROM");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC CHYBA SPOJENÍ");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("VÝMĚNA FILAMENTU");
diff --git a/Marlin/src/lcd/language/language_da.h b/Marlin/src/lcd/language/language_da.h
index 01281db2688..05474744d0a 100644
--- a/Marlin/src/lcd/language/language_da.h
+++ b/Marlin/src/lcd/language/language_da.h
@@ -74,7 +74,7 @@ namespace Language_da {
   LSTR MSG_MOVE_X                         = _UxGT("Flyt X");
   LSTR MSG_MOVE_Y                         = _UxGT("Flyt Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Flyt Z");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Flyt %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Flyt $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Flyt 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Flyt 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Flyt 10mm");
@@ -172,13 +172,7 @@ namespace Language_da {
   LSTR MSG_INFO_PSU                       = _UxGT("Strømfors.");
 
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Driv Styrke");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driv %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driv %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driv %");
 
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM Skriv");
 
diff --git a/Marlin/src/lcd/language/language_de.h b/Marlin/src/lcd/language/language_de.h
index 111608dd467..2b22319361a 100644
--- a/Marlin/src/lcd/language/language_de.h
+++ b/Marlin/src/lcd/language/language_de.h
@@ -84,12 +84,6 @@ namespace Language_de {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("Homeversatz X");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Homeversatz Y");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Homeversatz Z");
-  LSTR MSG_HOME_OFFSET_I                  = _UxGT("Homeversatz ") STR_I;
-  LSTR MSG_HOME_OFFSET_J                  = _UxGT("Homeversatz ") STR_J;
-  LSTR MSG_HOME_OFFSET_K                  = _UxGT("Homeversatz ") STR_K;
-  LSTR MSG_HOME_OFFSET_U                  = _UxGT("Homeversatz ") STR_U;
-  LSTR MSG_HOME_OFFSET_V                  = _UxGT("Homeversatz ") STR_V;
-  LSTR MSG_HOME_OFFSET_W                  = _UxGT("Homeversatz ") STR_W;
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Homeversatz aktiv");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Tramming Assistent");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Wählen Sie Ursprung");
@@ -273,13 +267,11 @@ namespace Language_de {
   LSTR MSG_MOVE_X                         = _UxGT("Bewege X");
   LSTR MSG_MOVE_Y                         = _UxGT("Bewege Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Bewege Z");
-  LSTR MSG_MOVE_I                         = _UxGT("Bewege ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Bewege ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Bewege ") STR_K;
+  LSTR MSG_MOVE_N                         = _UxGT("Bewege @");
   LSTR MSG_MOVE_E                         = _UxGT("Bewege Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Bewege Extruder *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hotend zu kalt");
-  LSTR MSG_MOVE_N_MM                      = _UxGT(" %s mm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT(" $ mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("  0,1  mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("  1,0  mm");
   LSTR MSG_MOVE_10MM                      = _UxGT(" 10,0  mm");
@@ -289,12 +281,6 @@ namespace Language_de {
   LSTR MSG_MOVE_01IN                      = _UxGT("0.100 in");
   LSTR MSG_MOVE_1IN                       = _UxGT("1.000 in");
   LSTR MSG_SPEED                          = _UxGT("Geschw.");
-  LSTR MSG_MAXSPEED                       = _UxGT("Max Geschw. (mm/s)");
-  LSTR MSG_MAXSPEED_X                     = _UxGT("Max ") STR_A _UxGT(" Geschw.");
-  LSTR MSG_MAXSPEED_Y                     = _UxGT("Max ") STR_B _UxGT(" Geschw.");
-  LSTR MSG_MAXSPEED_Z                     = _UxGT("Max ") STR_C _UxGT(" Geschw.");
-  LSTR MSG_MAXSPEED_E                     = _UxGT("Max ") STR_E _UxGT(" Geschw.");
-  LSTR MSG_MAXSPEED_A                     = _UxGT("Max @ Geschw.");
   LSTR MSG_BED_Z                          = _UxGT("Bett Z");
   LSTR MSG_NOZZLE                         = _UxGT("Düse");
   LSTR MSG_NOZZLE_N                       = _UxGT("Düse ~");
@@ -347,19 +333,15 @@ namespace Language_de {
   LSTR MSG_VA_JERK                        = _UxGT("Max ") STR_A _UxGT(" Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("Max ") STR_B _UxGT(" Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("Max ") STR_C _UxGT(" Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("Max ") STR_I _UxGT(" Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("Max ") STR_J _UxGT(" Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("Max ") STR_K _UxGT(" Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("Max @ Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Max E Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Junction Dev");
-  LSTR MSG_VELOCITY                       = _UxGT("Geschwindigkeit");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Geschw. (mm/s)");
   LSTR MSG_VMAX_A                         = _UxGT("V max ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("V max ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("V max ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("V max ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("V max ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("V max ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("V max ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("V max @");
+  LSTR MSG_VMAX_E                         = _UxGT("V max E");
   LSTR MSG_VMAX_EN                        = _UxGT("V max *");
   LSTR MSG_VMIN                           = _UxGT("V min ");
   LSTR MSG_VTRAV_MIN                      = _UxGT("V min Leerfahrt");
@@ -367,10 +349,8 @@ namespace Language_de {
   LSTR MSG_AMAX_A                         = _UxGT("A max ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("A max ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("A max ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("A max ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("A max ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("A max ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("A max ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("A max @");
+  LSTR MSG_AMAX_E                         = _UxGT("A max E");
   LSTR MSG_AMAX_EN                        = _UxGT("A max *");
   LSTR MSG_A_RETRACT                      = _UxGT("A Einzug");
   LSTR MSG_A_TRAVEL                       = _UxGT("A Leerfahrt");
@@ -380,10 +360,8 @@ namespace Language_de {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" Steps/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" Steps/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" Steps/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" Steps/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" Steps/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" Steps/mm");
-  LSTR MSG_E_STEPS                        = STR_E _UxGT(" Steps/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ Steps/mm");
+  LSTR MSG_E_STEPS                        = _UxGT("E Steps/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* Steps/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatur");
   LSTR MSG_MOTION                         = _UxGT("Bewegung");
@@ -533,9 +511,7 @@ namespace Language_de {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Babystep ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Babystep ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Babystep ") STR_K;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Abbr. mit Endstopp");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("HEIZEN ERFOLGLOS");
@@ -629,13 +605,7 @@ namespace Language_de {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Max Temp");
   LSTR MSG_INFO_PSU                       = _UxGT("Netzteil");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Motorleistung");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Treiber %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Treiber %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Treiber %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC Verbindungsfehler");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Werte speichern");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("FILAMENT WECHSEL");
diff --git a/Marlin/src/lcd/language/language_el.h b/Marlin/src/lcd/language/language_el.h
index 37056817565..47d6a5b2da3 100644
--- a/Marlin/src/lcd/language/language_el.h
+++ b/Marlin/src/lcd/language/language_el.h
@@ -119,17 +119,13 @@ namespace Language_el {
   LSTR MSG_VA_JERK                        = _UxGT("Vαντίδραση ") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("Vαντίδραση ") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("Vαντίδραση ") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("Vαντίδραση ") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("Vαντίδραση ") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("Vαντίδραση ") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("Vαντίδραση @");
   LSTR MSG_VE_JERK                        = _UxGT("Vαντίδραση E");
   LSTR MSG_VMAX_A                         = _UxGT("V Μέγιστο") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("V Μέγιστο") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("V Μέγιστο") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("V Μέγιστο") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("V Μέγιστο") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("V Μέγιστο") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("V Μέγιστο") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("V Μέγιστο@");
+  LSTR MSG_VMAX_E                         = _UxGT("V ΜέγιστοE");
   LSTR MSG_VMAX_EN                        = _UxGT("V Μέγιστο *");
   LSTR MSG_VMIN                           = _UxGT("V Ελάχιστο");
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vελάχ. μετατόπιση");
@@ -137,10 +133,8 @@ namespace Language_el {
   LSTR MSG_AMAX_A                         = _UxGT("Aμεγ ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Aμεγ ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Aμεγ ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Aμεγ ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Aμεγ ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Aμεγ ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Aμεγ ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Aμεγ @");
+  LSTR MSG_AMAX_E                         = _UxGT("Aμεγ E");
   LSTR MSG_AMAX_EN                        = _UxGT("Aμεγ *");
   LSTR MSG_A_RETRACT                      = _UxGT("Α-ανάσυρση");
   LSTR MSG_A_TRAVEL                       = _UxGT("Α-μετατόπιση");
@@ -148,9 +142,7 @@ namespace Language_el {
   LSTR MSG_A_STEPS                        = _UxGT("Bήματα ") STR_A _UxGT(" ανά μμ");
   LSTR MSG_B_STEPS                        = _UxGT("Bήματα ") STR_B _UxGT(" ανά μμ");
   LSTR MSG_C_STEPS                        = _UxGT("Bήματα ") STR_C _UxGT(" ανά μμ");
-  LSTR MSG_I_STEPS                        = _UxGT("Bήματα ") STR_I _UxGT(" ανά μμ");
-  LSTR MSG_J_STEPS                        = _UxGT("Bήματα ") STR_J _UxGT(" ανά μμ");
-  LSTR MSG_K_STEPS                        = _UxGT("Bήματα ") STR_K _UxGT(" ανά μμ");
+  LSTR MSG_N_STEPS                        = _UxGT("Bήματα @ ανά μμ");
   LSTR MSG_E_STEPS                        = _UxGT("Bήματα Ε ανά μμ");
   LSTR MSG_EN_STEPS                       = _UxGT("Bήματα * ανά μμ");
   LSTR MSG_TEMPERATURE                    = _UxGT("Θερμοκρασία");
diff --git a/Marlin/src/lcd/language/language_el_gr.h b/Marlin/src/lcd/language/language_el_gr.h
index b13893fb4cd..bd2e7d595d9 100644
--- a/Marlin/src/lcd/language/language_el_gr.h
+++ b/Marlin/src/lcd/language/language_el_gr.h
@@ -109,17 +109,13 @@ namespace Language_el_gr {
   LSTR MSG_VA_JERK                        = _UxGT("Vαντίδραση ") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("Vαντίδραση ") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("Vαντίδραση ") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("Vαντίδραση ") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("Vαντίδραση ") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("Vαντίδραση ") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("Vαντίδραση @");
   LSTR MSG_VE_JERK                        = _UxGT("Vαντίδραση E");
   LSTR MSG_VMAX_A                         = _UxGT("Vμεγ ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("Vμεγ ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Vμεγ ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vμεγ ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vμεγ ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vμεγ ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vμεγ ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Vμεγ @");
+  LSTR MSG_VMAX_E                         = _UxGT("Vμεγ E");
   LSTR MSG_VMAX_EN                        = _UxGT("Vμεγ *");
   LSTR MSG_VMIN                           = _UxGT("Vελαχ");
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vελάχ. μετατόπιση");
@@ -127,10 +123,8 @@ namespace Language_el_gr {
   LSTR MSG_AMAX_A                         = _UxGT("Aμεγ ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Aμεγ ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Aμεγ ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Aμεγ ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Aμεγ ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Aμεγ ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Aμεγ ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Aμεγ @");
+  LSTR MSG_AMAX_E                         = _UxGT("Aμεγ E");
   LSTR MSG_AMAX_EN                        = _UxGT("Aμεγ *");
   LSTR MSG_A_RETRACT                      = _UxGT("Α-ανάσυρση");
   LSTR MSG_A_TRAVEL                       = _UxGT("Α-μετατόπιση");
@@ -138,9 +132,7 @@ namespace Language_el_gr {
   LSTR MSG_A_STEPS                        = _UxGT("Bήματα ") STR_A _UxGT(" ανά μμ");
   LSTR MSG_B_STEPS                        = _UxGT("Bήματα ") STR_B _UxGT(" ανά μμ");
   LSTR MSG_C_STEPS                        = _UxGT("Bήματα ") STR_C _UxGT(" ανά μμ");
-  LSTR MSG_I_STEPS                        = _UxGT("Bήματα ") STR_I _UxGT(" ανά μμ");
-  LSTR MSG_J_STEPS                        = _UxGT("Bήματα ") STR_J _UxGT(" ανά μμ");
-  LSTR MSG_K_STEPS                        = _UxGT("Bήματα ") STR_K _UxGT(" ανά μμ");
+  LSTR MSG_N_STEPS                        = _UxGT("Bήματα @ ανά μμ");
   LSTR MSG_E_STEPS                        = _UxGT("Bήματα Ε ανά μμ");
   LSTR MSG_EN_STEPS                       = _UxGT("Bήματα * ανά μμ");
   LSTR MSG_TEMPERATURE                    = _UxGT("Θερμοκρασία");
diff --git a/Marlin/src/lcd/language/language_en.h b/Marlin/src/lcd/language/language_en.h
index 90607e82459..81f30b61d8e 100644
--- a/Marlin/src/lcd/language/language_en.h
+++ b/Marlin/src/lcd/language/language_en.h
@@ -27,10 +27,9 @@
  * LCD Menu Messages
  * See also https://marlinfw.org/docs/development/lcd_language.html
  *
- * Substitutions are applied for the following characters when used
- * in menu items that call lcd_put_u8str_ind_P with an index:
+ * Substitutions are applied for the following characters when used in menu items titles:
  *
- *   $ displays an inserted C-string
+ *   $ displays an inserted string
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
@@ -106,9 +105,6 @@ namespace Language_en {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("Home Offset X");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Home Offset Y");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Home Offset Z");
-  LSTR MSG_HOME_OFFSET_I                  = _UxGT("Home Offset ") STR_I;
-  LSTR MSG_HOME_OFFSET_J                  = _UxGT("Home Offset ") STR_J;
-  LSTR MSG_HOME_OFFSET_K                  = _UxGT("Home Offset ") STR_K;
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Offsets Applied");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Tramming Wizard");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Select Origin");
@@ -311,13 +307,11 @@ namespace Language_en {
   LSTR MSG_MOVE_X                         = _UxGT("Move X"); // Used by draw_edit_screen
   LSTR MSG_MOVE_Y                         = _UxGT("Move Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Move Z");
-  LSTR MSG_MOVE_I                         = _UxGT("Move ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Move ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Move ") STR_K;
+  LSTR MSG_MOVE_N                         = _UxGT("Move @");
   LSTR MSG_MOVE_E                         = _UxGT("Move Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Move E*");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hotend too cold");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Move %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Move $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Move 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Move 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Move 10mm");
@@ -327,12 +321,6 @@ namespace Language_en {
   LSTR MSG_MOVE_01IN                      = _UxGT("Move 0.1in");
   LSTR MSG_MOVE_1IN                       = _UxGT("Move 1.0in");
   LSTR MSG_SPEED                          = _UxGT("Speed");
-  LSTR MSG_MAXSPEED                       = _UxGT("Max Speed (mm/s)");
-  LSTR MSG_MAXSPEED_X                     = _UxGT("Max ") STR_A _UxGT(" Speed");
-  LSTR MSG_MAXSPEED_Y                     = _UxGT("Max ") STR_B _UxGT(" Speed");
-  LSTR MSG_MAXSPEED_Z                     = _UxGT("Max ") STR_C _UxGT(" Speed");
-  LSTR MSG_MAXSPEED_E                     = _UxGT("Max ") STR_E _UxGT(" Speed");
-  LSTR MSG_MAXSPEED_A                     = _UxGT("Max @ Speed");
   LSTR MSG_BED_Z                          = _UxGT("Bed Z");
   LSTR MSG_NOZZLE                         = _UxGT("Nozzle");
   LSTR MSG_NOZZLE_N                       = _UxGT("Nozzle ~");
@@ -389,30 +377,24 @@ namespace Language_en {
   LSTR MSG_VA_JERK                        = _UxGT("Max ") STR_A _UxGT(" Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("Max ") STR_B _UxGT(" Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("Max ") STR_C _UxGT(" Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("Max ") STR_I _UxGT(" Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("Max ") STR_J _UxGT(" Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("Max ") STR_K _UxGT(" Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("Max @ Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Max E Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Junction Dev");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocity");
-  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Vel");
-  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Vel");
-  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Vel");
-  LSTR MSG_VMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Vel");
-  LSTR MSG_VMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Vel");
-  LSTR MSG_VMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Vel");
-  LSTR MSG_VMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Vel");
-  LSTR MSG_VMAX_EN                        = _UxGT("Max * Vel");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Speed (mm/s)");
+  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Speed");
+  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Speed");
+  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Speed");
+  LSTR MSG_VMAX_N                         = _UxGT("Max @ Speed");
+  LSTR MSG_VMAX_E                         = _UxGT("Max E Speed");
+  LSTR MSG_VMAX_EN                        = _UxGT("Max * Speed");
   LSTR MSG_VMIN                           = _UxGT("Min Velocity");
-  LSTR MSG_VTRAV_MIN                      = _UxGT("Min Travel Vel");
+  LSTR MSG_VTRAV_MIN                      = _UxGT("Min Travel Speed");
   LSTR MSG_ACCELERATION                   = _UxGT("Acceleration");
   LSTR MSG_AMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Accel");
   LSTR MSG_AMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Accel");
   LSTR MSG_AMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Accel");
-  LSTR MSG_AMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Accel");
-  LSTR MSG_AMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Accel");
-  LSTR MSG_AMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Accel");
-  LSTR MSG_AMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Accel");
+  LSTR MSG_AMAX_N                         = _UxGT("Max @ Accel");
+  LSTR MSG_AMAX_E                         = _UxGT("Max E Accel");
   LSTR MSG_AMAX_EN                        = _UxGT("Max * Accel");
   LSTR MSG_A_RETRACT                      = _UxGT("Retract Accel");
   LSTR MSG_A_TRAVEL                       = _UxGT("Travel Accel");
@@ -422,9 +404,7 @@ namespace Language_en {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" Steps/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" Steps/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" Steps/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" Steps/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" Steps/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" Steps/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ steps/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E steps/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* Steps/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperature");
@@ -587,9 +567,7 @@ namespace Language_en {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Babystep ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Babystep ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Babystep ") STR_K;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop Abort");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Heating Failed");
@@ -686,13 +664,7 @@ namespace Language_en {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Max Temp");
   LSTR MSG_INFO_PSU                       = _UxGT("PSU");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Drive Strength");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC CONNECTION ERROR");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM Write");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("FILAMENT CHANGE");
@@ -865,12 +837,7 @@ namespace Language_en {
   LSTR MSG_PID_C_E                        = _UxGT("PID-C *");
   LSTR MSG_PID_F                          = _UxGT("PID-F");
   LSTR MSG_PID_F_E                        = _UxGT("PID-F *");
-  LSTR MSG_BACKLASH_A                     = STR_A;
-  LSTR MSG_BACKLASH_B                     = STR_B;
-  LSTR MSG_BACKLASH_C                     = STR_C;
-  LSTR MSG_BACKLASH_I                     = STR_I;
-  LSTR MSG_BACKLASH_J                     = STR_J;
-  LSTR MSG_BACKLASH_K                     = STR_K;
+  LSTR MSG_BACKLASH_N                     = _UxGT("@");
 }
 
 #if FAN_COUNT == 1
diff --git a/Marlin/src/lcd/language/language_es.h b/Marlin/src/lcd/language/language_es.h
index 4eb7c9f7e1a..cc331efd456 100644
--- a/Marlin/src/lcd/language/language_es.h
+++ b/Marlin/src/lcd/language/language_es.h
@@ -229,7 +229,7 @@ namespace Language_es {
   LSTR MSG_MOVE_E                         = _UxGT("Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrusor *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hotend muy frio");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mover 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mover 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mover 10mm");
@@ -270,30 +270,24 @@ namespace Language_es {
   LSTR MSG_VA_JERK                        = _UxGT("Max ") STR_A _UxGT(" Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("Max ") STR_B _UxGT(" Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("Max ") STR_C _UxGT(" Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("Max ") STR_I _UxGT(" Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("Max ") STR_J _UxGT(" Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("Max ") STR_K _UxGT(" Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("Max @ Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Max E Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Desvi. Unión");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocidad");
-  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Vel");
-  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Vel");
-  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Vel");
-  LSTR MSG_VMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Vel");
-  LSTR MSG_VMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Vel");
-  LSTR MSG_VMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Vel");
-  LSTR MSG_VMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Vel");
-  LSTR MSG_VMAX_EN                        = _UxGT("Max * Vel");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Velocidad");
+  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Speed");
+  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Speed");
+  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Speed");
+  LSTR MSG_VMAX_N                         = _UxGT("Max @ Speed");
+  LSTR MSG_VMAX_E                         = _UxGT("Max E Speed");
+  LSTR MSG_VMAX_EN                        = _UxGT("Max * Speed");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vel. viaje min");
   LSTR MSG_ACCELERATION                   = _UxGT("Acceleración");
   LSTR MSG_AMAX_A                         = _UxGT("Acel. max") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Acel. max") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Acel. max") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Acel. max") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Acel. max") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Acel. max") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Acel. max") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Acel. max@");
+  LSTR MSG_AMAX_E                         = _UxGT("Acel. maxE");
   LSTR MSG_AMAX_EN                        = _UxGT("Acel. max *");
   LSTR MSG_A_RETRACT                      = _UxGT("Acel. retrac.");
   LSTR MSG_A_TRAVEL                       = _UxGT("Acel. Viaje");
@@ -301,9 +295,7 @@ namespace Language_es {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" pasos/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" pasos/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" pasos/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" pasos/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" pasos/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" pasos/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ pasos/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E pasos/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* pasos/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -413,6 +405,7 @@ namespace Language_es {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Micropaso X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Micropaso Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Micropaso Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Micropaso @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Cancelado - Endstop");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Calent. fallido");
@@ -480,13 +473,7 @@ namespace Language_es {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Temp. Máxima");
   LSTR MSG_INFO_PSU                       = _UxGT("F. Aliment.");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Fuerza de empuje");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_ERROR_TMC                      = _UxGT("ERROR CONEX. TMC");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Escribe DAC EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("CAMBIAR FILAMENTO");
diff --git a/Marlin/src/lcd/language/language_eu.h b/Marlin/src/lcd/language/language_eu.h
index 2d84518f0bf..09a0fbeb6ac 100644
--- a/Marlin/src/lcd/language/language_eu.h
+++ b/Marlin/src/lcd/language/language_eu.h
@@ -138,7 +138,7 @@ namespace Language_eu {
   LSTR MSG_MOVE_Z                         = _UxGT("Mugitu Z");
   LSTR MSG_MOVE_E                         = _UxGT("Estrusorea");
   LSTR MSG_MOVE_EN                        = _UxGT("Estrusorea *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mugitu %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mugitu $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mugitu 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mugitu 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mugitu 10mm");
@@ -166,9 +166,7 @@ namespace Language_eu {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT("-astindua");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT("-astindua");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT("-astindua");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT("-astindua");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT("-astindua");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT("-astindua");
+  LSTR MSG_VN_JERK                        = _UxGT("V@-astindua");
   LSTR MSG_VE_JERK                        = _UxGT("Ve-astindua");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VBidaia min");
   LSTR MSG_A_RETRACT                      = _UxGT("A-retrakt");
@@ -177,9 +175,7 @@ namespace Language_eu {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" pausoak/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" pausoak/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" pausoak/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" pausoak/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" pausoak/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" pausoak/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ pausoak/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E pausoak/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* pausoak/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Tenperatura");
@@ -243,6 +239,7 @@ namespace Language_eu {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Mikro-urratsa X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Mikro-urratsa Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Mikro-urratsa Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Mikro-urratsa @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop deusezta.");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Err: Beroketa");
   LSTR MSG_ERR_REDUNDANT_TEMP             = _UxGT("Err: Tenperatura");
@@ -296,13 +293,7 @@ namespace Language_eu {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Tenp. Maximoa");
   LSTR MSG_INFO_PSU                       = _UxGT("Elikadura-iturria");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Driver-aren potentzia");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Idatzi DAC EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER_PAUSE   = _UxGT("HARIZPIA ALDATU");
   LSTR MSG_FILAMENT_CHANGE_HEADER_LOAD    = _UxGT("HARIZPIA KARGATU");
diff --git a/Marlin/src/lcd/language/language_fi.h b/Marlin/src/lcd/language/language_fi.h
index 066179c9504..8fd53a79e36 100644
--- a/Marlin/src/lcd/language/language_fi.h
+++ b/Marlin/src/lcd/language/language_fi.h
@@ -71,7 +71,7 @@ namespace Language_fi {
   LSTR MSG_MOVE_Z                         = _UxGT("Liikuta Z");
   LSTR MSG_MOVE_E                         = _UxGT("Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Extruder *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Liikuta %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Liikuta $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Liikuta 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Liikuta 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Liikuta 10mm");
diff --git a/Marlin/src/lcd/language/language_fr.h b/Marlin/src/lcd/language/language_fr.h
index f3ea9b5e3b8..6081234607f 100644
--- a/Marlin/src/lcd/language/language_fr.h
+++ b/Marlin/src/lcd/language/language_fr.h
@@ -72,9 +72,6 @@ namespace Language_fr {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("Décal. origine X");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Décal. origine Y");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Décal. origine Z");
-  LSTR MSG_HOME_OFFSET_I                  = _UxGT("Décal. origine ") STR_I;
-  LSTR MSG_HOME_OFFSET_J                  = _UxGT("Décal. origine ") STR_J;
-  LSTR MSG_HOME_OFFSET_K                  = _UxGT("Décal. origine ") STR_K;
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Décalages appliqués");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Assistant Molettes");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Molette du lit"); // Not a selection of the origin
@@ -233,13 +230,11 @@ namespace Language_fr {
   LSTR MSG_MOVE_X                         = _UxGT("Déplacer X");
   LSTR MSG_MOVE_Y                         = _UxGT("Déplacer Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Déplacer Z");
-  LSTR MSG_MOVE_I                         = _UxGT("Déplacer ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Déplacer ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Déplacer ") STR_K;
+  LSTR MSG_MOVE_N                         = _UxGT("Déplacer @");
   LSTR MSG_MOVE_E                         = _UxGT("Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Extruder *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Buse trop froide");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Déplacer %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Déplacer $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Déplacer 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Déplacer 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Déplacer 10mm");
@@ -282,18 +277,14 @@ namespace Language_fr {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT(" jerk");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT(" jerk");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT(" jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT(" jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT(" jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT(" jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("V@ jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Ve jerk");
-  LSTR MSG_VELOCITY                       = _UxGT("Vélocité");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Vélocité");
   LSTR MSG_VMAX_A                         = _UxGT("Vit. Max ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("Vit. Max ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Vit. Max ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vit. Max ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vit. Max ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vit. Max ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vit. Max ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Vit. Max @");
+  LSTR MSG_VMAX_E                         = _UxGT("Vit. Max E");
   LSTR MSG_VMAX_EN                        = _UxGT("Vit. Max *");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Déviat. jonct.");
   LSTR MSG_VMIN                           = _UxGT("Vit. Min");
@@ -302,10 +293,8 @@ namespace Language_fr {
   LSTR MSG_AMAX_A                         = _UxGT("Max Accél. ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Max Accél. ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Max Accél. ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Max Accél. ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Max Accél. ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Max Accél. ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Max Accél. ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Max Accél. @");
+  LSTR MSG_AMAX_E                         = _UxGT("Max Accél. E");
   LSTR MSG_AMAX_EN                        = _UxGT("Max Accél. *");
   LSTR MSG_A_RETRACT                      = _UxGT("Acc.rétraction");
   LSTR MSG_A_TRAVEL                       = _UxGT("Acc.course");
@@ -315,9 +304,7 @@ namespace Language_fr {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" pas/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" pas/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" pas/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" pas/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" pas/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" pas/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ pas/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E pas/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* pas/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Température");
@@ -443,9 +430,7 @@ namespace Language_fr {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Babystep ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Babystep ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Babystep ") STR_K;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Butée abandon");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Err de chauffe");
@@ -521,13 +506,7 @@ namespace Language_fr {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Temp Max");
   LSTR MSG_INFO_PSU                       = _UxGT("Alim.");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Puiss. moteur ");
-  LSTR MSG_DAC_PERCENT_A                  = _UxGT("Driver ") STR_A _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_B                  = _UxGT("Driver ") STR_B _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_C                  = _UxGT("Driver ") STR_C _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_I                  = _UxGT("Driver ") STR_I _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_J                  = _UxGT("Driver ") STR_J _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_K                  = _UxGT("Driver ") STR_K _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("Driver E %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("Driver @ %");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM sauv.");
   LSTR MSG_ERROR_TMC                      = _UxGT("ERREUR CONNEXION TMC");
 
diff --git a/Marlin/src/lcd/language/language_gl.h b/Marlin/src/lcd/language/language_gl.h
index 55dc03ac9d9..dabd35efcf9 100644
--- a/Marlin/src/lcd/language/language_gl.h
+++ b/Marlin/src/lcd/language/language_gl.h
@@ -226,7 +226,7 @@ namespace Language_gl {
   LSTR MSG_MOVE_E                         = _UxGT("Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrusor *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Bico moi frío");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mover 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mover 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mover 10mm");
@@ -271,30 +271,23 @@ namespace Language_gl {
   LSTR MSG_VA_JERK                        = _UxGT("Max ") STR_A _UxGT(" Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("Max ") STR_B _UxGT(" Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("Max ") STR_C _UxGT(" Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("Max ") STR_I _UxGT(" Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("Max ") STR_J _UxGT(" Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("Max ") STR_K _UxGT(" Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("Max @ Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Max E Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Desvío Unión");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocidade");
-  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Vel");
-  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Vel");
-  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Vel");
-  LSTR MSG_VMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Vel");
-  LSTR MSG_VMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Vel");
-  LSTR MSG_VMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Vel");
-  LSTR MSG_VMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Vel");
-  LSTR MSG_VMAX_EN                        = _UxGT("Max * Vel");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Velocidade");
+  LSTR MSG_VMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Speed");
+  LSTR MSG_VMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Speed");
+  LSTR MSG_VMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Speed");
+  LSTR MSG_VMAX_N                         = _UxGT("Max @ Speed");
+  LSTR MSG_VMAX_E                         = _UxGT("Max E Speed");
+  LSTR MSG_VMAX_EN                        = _UxGT("Max * Speed");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("V-viaxe min");
   LSTR MSG_ACCELERATION                   = _UxGT("Aceleración");
   LSTR MSG_AMAX_A                         = _UxGT("Max ") STR_A _UxGT(" Accel");
   LSTR MSG_AMAX_B                         = _UxGT("Max ") STR_B _UxGT(" Accel");
   LSTR MSG_AMAX_C                         = _UxGT("Max ") STR_C _UxGT(" Accel");
-  LSTR MSG_AMAX_I                         = _UxGT("Max ") STR_I _UxGT(" Accel");
-  LSTR MSG_AMAX_J                         = _UxGT("Max ") STR_J _UxGT(" Accel");
-  LSTR MSG_AMAX_K                         = _UxGT("Max ") STR_K _UxGT(" Accel");
-  LSTR MSG_AMAX_E                         = _UxGT("Max ") STR_E _UxGT(" Accel");
+  LSTR MSG_AMAX_E                         = _UxGT("Max E Accel");
   LSTR MSG_AMAX_EN                        = _UxGT("Max * Accel");
   LSTR MSG_A_RETRACT                      = _UxGT("A-retrac.");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-viaxe");
@@ -304,9 +297,7 @@ namespace Language_gl {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" pasos/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" pasos/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" pasos/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" pasos/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" pasos/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" pasos/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ pasos/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E pasos/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* pasos/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -429,6 +420,7 @@ namespace Language_gl {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Micropaso X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Micropaso Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Micropaso Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Micropaso @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Erro FinCarro");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Fallo Quentando");
@@ -496,13 +488,7 @@ namespace Language_gl {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Temp Máx");
   LSTR MSG_INFO_PSU                       = _UxGT("Fonte Alimentación");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Forza do Motor");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_ERROR_TMC                      = _UxGT("ERRO CONEX. TMC");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Escribe DAC EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("CAMBIAR FILAMENTO");
diff --git a/Marlin/src/lcd/language/language_hr.h b/Marlin/src/lcd/language/language_hr.h
index 40705bbc91d..10f11f616f5 100644
--- a/Marlin/src/lcd/language/language_hr.h
+++ b/Marlin/src/lcd/language/language_hr.h
@@ -78,7 +78,7 @@ namespace Language_hr {
   LSTR MSG_LEVEL_BED                      = _UxGT("Niveliraj bed");
   LSTR MSG_MOVE_X                         = _UxGT("Miči X");
   LSTR MSG_MOVE_Y                         = _UxGT("Miči Y");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Miči %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Miči $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Miči 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Miči 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Miči 10mm");
diff --git a/Marlin/src/lcd/language/language_hu.h b/Marlin/src/lcd/language/language_hu.h
index 6321ed13674..81db96df170 100644
--- a/Marlin/src/lcd/language/language_hu.h
+++ b/Marlin/src/lcd/language/language_hu.h
@@ -79,9 +79,6 @@ namespace Language_hu {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("X Kezdö eltol.");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Y Kezdö eltol.");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Z Kezdö eltol.");
-  LSTR MSG_HOME_OFFSET_I                  = _UxGT("Kezdö eltol. ") STR_I;
-  LSTR MSG_HOME_OFFSET_J                  = _UxGT("Kezdö eltol. ") STR_J;
-  LSTR MSG_HOME_OFFSET_K                  = _UxGT("Kezdö eltol. ") STR_K;
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Eltolás beállítva.");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Elektromos varázsló");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Eredeti választása");
@@ -259,13 +256,11 @@ namespace Language_hu {
   LSTR MSG_MOVE_X                         = _UxGT("X mozgás");
   LSTR MSG_MOVE_Y                         = _UxGT("Y mozgás");
   LSTR MSG_MOVE_Z                         = _UxGT("Z mozgás");
-  LSTR MSG_MOVE_I                         = _UxGT("Mozgás ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Mozgás ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Mozgás ") STR_K;
+  LSTR MSG_MOVE_N                         = _UxGT("@ mozgás");
   LSTR MSG_MOVE_E                         = _UxGT("Adagoló");
   LSTR MSG_MOVE_EN                        = _UxGT("Adagoló *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("A fej túl hideg");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mozgás %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mozgás $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mozgás 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mozgás 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mozgás 10mm");
@@ -319,19 +314,15 @@ namespace Language_hu {
   LSTR MSG_VA_JERK                        = _UxGT("Seb.") STR_A _UxGT("-Rántás");
   LSTR MSG_VB_JERK                        = _UxGT("Seb.") STR_B _UxGT("-Rántás");
   LSTR MSG_VC_JERK                        = _UxGT("Seb.") STR_C _UxGT("-Rántás");
-  LSTR MSG_VI_JERK                        = _UxGT("Seb.") STR_I _UxGT("-Rántás");
-  LSTR MSG_VJ_JERK                        = _UxGT("Seb.") STR_J _UxGT("-Rántás");
-  LSTR MSG_VK_JERK                        = _UxGT("Seb.") STR_K _UxGT("-Rántás");
+  LSTR MSG_VN_JERK                        = _UxGT("Seb.@-Rántás");
   LSTR MSG_VE_JERK                        = _UxGT("E ránt. seb.");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Csomopont eltérés");
-  LSTR MSG_VELOCITY                       = _UxGT("Sebesség");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Sebesség (mm/s)");
   LSTR MSG_VMAX_A                         = _UxGT("Max Seb. ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("Max Seb. ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Max Seb. ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Max Seb. ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Max Seb. ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Max Seb. ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Max Seb. ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Max Seb. @");
+  LSTR MSG_VMAX_E                         = _UxGT("Max Seb. E");
   LSTR MSG_VMAX_EN                        = _UxGT("Max sebesség *");
   LSTR MSG_VMIN                           = _UxGT("Min sebesség");
   LSTR MSG_VTRAV_MIN                      = _UxGT("Min utazó.seb.");
@@ -339,10 +330,8 @@ namespace Language_hu {
   LSTR MSG_AMAX_A                         = _UxGT("Max gyors. ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Max gyors. ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Max gyors. ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Max gyors. ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Max gyors. ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Max gyors. ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Max gyors. ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Max gyors. @");
+  LSTR MSG_AMAX_E                         = _UxGT("Max gyors. E");
   LSTR MSG_AMAX_EN                        = _UxGT("Max gyorsulás *");
   LSTR MSG_A_RETRACT                      = _UxGT("Visszahúzás");
   LSTR MSG_A_TRAVEL                       = _UxGT("Utazás");
@@ -352,9 +341,7 @@ namespace Language_hu {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" Lépés/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" Lépés/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" Lépés/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" Lépés/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" Lépés/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" Lépés/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ lépés/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E lépés/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("*Lépés/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Höfok");
@@ -488,9 +475,7 @@ namespace Language_hu {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Mikrolépés X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Mikrolépés Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Mikrolépés Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Mikrolépés ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Mikrolépés ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Mikrolépés ") STR_K;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Mikrolépés @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Teljes");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Végállás megszakítva!");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Fütés hiba!");
@@ -568,13 +553,7 @@ namespace Language_hu {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Max höfok");
   LSTR MSG_INFO_PSU                       = _UxGT("PSU");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Meghajtási erö");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Meghajtó %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E meghajtó %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ meghajtó %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC CSATLAKOZÁSI HIBA");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM írása");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("NYOMTATÓSZÁL CSERE");
diff --git a/Marlin/src/lcd/language/language_it.h b/Marlin/src/lcd/language/language_it.h
index 82c595aa8c2..b043ac26e16 100644
--- a/Marlin/src/lcd/language/language_it.h
+++ b/Marlin/src/lcd/language/language_it.h
@@ -27,10 +27,9 @@
  * LCD Menu Messages
  * See also https://marlinfw.org/docs/development/lcd_language.html
  *
- * Substitutions are applied for the following characters when used
- * in menu items that call lcd_put_u8str_ind_P with an index:
+ * Substitutions are applied for the following characters when used in menu items titles:
  *
- *   $ displays an inserted C-string
+ *   $ displays an inserted string
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
@@ -95,12 +94,6 @@ namespace Language_it {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("Offset home X");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Offset home Y");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Offset home Z");
-  LSTR MSG_HOME_OFFSET_I                  = _UxGT("Offset home ") STR_I;
-  LSTR MSG_HOME_OFFSET_J                  = _UxGT("Offset home ") STR_J;
-  LSTR MSG_HOME_OFFSET_K                  = _UxGT("Offset home ") STR_K;
-  LSTR MSG_HOME_OFFSET_U                  = _UxGT("Offset home ") STR_U;
-  LSTR MSG_HOME_OFFSET_V                  = _UxGT("Offset home ") STR_V;
-  LSTR MSG_HOME_OFFSET_W                  = _UxGT("Offset home ") STR_W;
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Offset applicato");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Wizard Tramming");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Selez. origine");
@@ -284,16 +277,11 @@ namespace Language_it {
   LSTR MSG_MOVE_X                         = _UxGT("Muovi X");
   LSTR MSG_MOVE_Y                         = _UxGT("Muovi Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Muovi Z");
-  LSTR MSG_MOVE_I                         = _UxGT("Muovi ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Muovi ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Muovi ") STR_K;
-  LSTR MSG_MOVE_U                         = _UxGT("Muovi ") STR_U;
-  LSTR MSG_MOVE_V                         = _UxGT("Muovi ") STR_V;
-  LSTR MSG_MOVE_W                         = _UxGT("Muovi ") STR_W;
+  LSTR MSG_MOVE_N                         = _UxGT("Muovi @");
   LSTR MSG_MOVE_E                         = _UxGT("Estrusore");
   LSTR MSG_MOVE_EN                        = _UxGT("Estrusore *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Ugello freddo");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Muovi di %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Muovi di $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Muovi di 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Muovi di 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Muovi di 10mm");
@@ -302,13 +290,6 @@ namespace Language_it {
   LSTR MSG_MOVE_001IN                     = _UxGT("Muovi di 0.01\"");
   LSTR MSG_MOVE_01IN                      = _UxGT("Muovi di 0.1\"");
   LSTR MSG_MOVE_1IN                       = _UxGT("Muovi di 1\"");
-  LSTR MSG_SPEED                          = _UxGT("Velocità");
-  LSTR MSG_MAXSPEED                       = _UxGT("Vel.massima (mm/s)");
-  LSTR MSG_MAXSPEED_X                     = _UxGT("Vel.massima ") STR_A;
-  LSTR MSG_MAXSPEED_Y                     = _UxGT("Vel.massima ") STR_B;
-  LSTR MSG_MAXSPEED_Z                     = _UxGT("Vel.massima ") STR_C;
-  LSTR MSG_MAXSPEED_E                     = _UxGT("Vel.massima ") STR_E;
-  LSTR MSG_MAXSPEED_A                     = _UxGT("Vel.massima @");
   LSTR MSG_BED_Z                          = _UxGT("Piatto Z");
   LSTR MSG_NOZZLE                         = _UxGT("Ugello");
   LSTR MSG_NOZZLE_N                       = _UxGT("Ugello ~");
@@ -361,25 +342,15 @@ namespace Language_it {
   LSTR MSG_VA_JERK                        = _UxGT("Max Jerk ") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("Max Jerk ") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("Max Jerk ") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("Max Jerk ") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("Max Jerk ") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("Max Jerk ") STR_K;
-  LSTR MSG_VU_JERK                        = _UxGT("Max Jerk ") STR_U;
-  LSTR MSG_VV_JERK                        = _UxGT("Max Jerk ") STR_V;
-  LSTR MSG_VW_JERK                        = _UxGT("Max Jerk ") STR_W;
+  LSTR MSG_VN_JERK                        = _UxGT("Max Jerk @");
   LSTR MSG_VE_JERK                        = _UxGT("Max Jerk E");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Deviaz. giunzioni");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocità");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Vel.massima (mm/s)");
   LSTR MSG_VMAX_A                         = _UxGT("Vel.Massima ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("Vel.Massima ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Vel.Massima ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vel.Massima ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vel.Massima ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vel.Massima ") STR_K;
-  LSTR MSG_VMAX_U                         = _UxGT("Vel.Massima ") STR_U;
-  LSTR MSG_VMAX_V                         = _UxGT("Vel.Massima ") STR_V;
-  LSTR MSG_VMAX_W                         = _UxGT("Vel.Massima ") STR_W;
-  LSTR MSG_VMAX_E                         = _UxGT("Vel.Massima ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Vel.Massima @");
+  LSTR MSG_VMAX_E                         = _UxGT("Vel.Massima E");
   LSTR MSG_VMAX_EN                        = _UxGT("Vel.Massima *");
   LSTR MSG_VMIN                           = _UxGT("Vel.Minima");
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vel.Min spostam.");
@@ -387,13 +358,8 @@ namespace Language_it {
   LSTR MSG_AMAX_A                         = _UxGT("Acc.Massima ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Acc.Massima ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Acc.Massima ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Acc.Massima ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Acc.Massima ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Acc.Massima ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Acc.Massima ") STR_E;
-  LSTR MSG_AMAX_U                         = _UxGT("Acc.Massima ") STR_U;
-  LSTR MSG_AMAX_V                         = _UxGT("Acc.Massima ") STR_V;
-  LSTR MSG_AMAX_W                         = _UxGT("Acc.Massima ") STR_W;
+  LSTR MSG_AMAX_N                         = _UxGT("Acc.Massima @");
+  LSTR MSG_AMAX_E                         = _UxGT("Acc.Massima E");
   LSTR MSG_AMAX_EN                        = _UxGT("Acc.Massima *");
   LSTR MSG_A_RETRACT                      = _UxGT("A-Ritrazione");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-Spostamento");
@@ -403,12 +369,7 @@ namespace Language_it {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" passi/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" passi/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" passi/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" passi/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" passi/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" passi/mm");
-  LSTR MSG_U_STEPS                        = STR_U _UxGT(" passi/mm");
-  LSTR MSG_V_STEPS                        = STR_V _UxGT(" passi/mm");
-  LSTR MSG_W_STEPS                        = STR_W _UxGT(" passi/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ passi/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E passi/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* passi/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -560,12 +521,7 @@ namespace Language_it {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Babystep ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Babystep ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Babystep ") STR_K;
-  LSTR MSG_BABYSTEP_U                     = _UxGT("Babystep ") STR_U;
-  LSTR MSG_BABYSTEP_V                     = _UxGT("Babystep ") STR_V;
-  LSTR MSG_BABYSTEP_W                     = _UxGT("Babystep ") STR_W;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Totali");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Interrompi se FC");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Risc.Fallito");   // Max 12 characters
@@ -658,16 +614,7 @@ namespace Language_it {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Temp max");
   LSTR MSG_INFO_PSU                       = _UxGT("Alimentatore");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Potenza Drive");
-  LSTR MSG_DAC_PERCENT_A                  = _UxGT("Driver ") STR_A _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_B                  = _UxGT("Driver ") STR_B _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_C                  = _UxGT("Driver ") STR_C _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_I                  = _UxGT("Driver ") STR_I _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_J                  = _UxGT("Driver ") STR_J _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_K                  = _UxGT("Driver ") STR_K _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_U                  = _UxGT("Driver ") STR_U _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_V                  = _UxGT("Driver ") STR_V _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_W                  = _UxGT("Driver ") STR_W _UxGT(" %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("Driver E %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("Driver @ %");
   LSTR MSG_ERROR_TMC                      = _UxGT("ERR.CONNESSIONE TMC");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Scrivi DAC EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("CAMBIO FILAMENTO");
diff --git a/Marlin/src/lcd/language/language_jp_kana.h b/Marlin/src/lcd/language/language_jp_kana.h
index 01d1c0b987e..0a53ee50d21 100644
--- a/Marlin/src/lcd/language/language_jp_kana.h
+++ b/Marlin/src/lcd/language/language_jp_kana.h
@@ -93,7 +93,7 @@ namespace Language_jp_kana {
   LSTR MSG_MOVE_Y                         = _UxGT("Yジク イドウ");                  // "Move Y"
   LSTR MSG_MOVE_Z                         = _UxGT("Zジク イドウ");                  // "Move Z"
   LSTR MSG_MOVE_E                         = _UxGT("エクストルーダー");                // "Extruder"
-  LSTR MSG_MOVE_N_MM                      = _UxGT("%smm イドウ");                  // "Move 0.025mm"
+  LSTR MSG_MOVE_N_MM                      = _UxGT("$mm イドウ");                    // "Move 0.025mm"
   LSTR MSG_MOVE_01MM                      = _UxGT("0.1mm イドウ");                 // "Move 0.1mm"
   LSTR MSG_MOVE_1MM                       = _UxGT("  1mm イドウ");                 // "Move 1mm"
   LSTR MSG_MOVE_10MM                      = _UxGT(" 10mm イドウ");                 // "Move 10mm"
@@ -118,20 +118,16 @@ namespace Language_jp_kana {
   LSTR MSG_VA_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_A;             // "Va-jerk"
   LSTR MSG_VB_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_B;             // "Vb-jerk"
   LSTR MSG_VC_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_C;             // "Vc-jerk"
-  LSTR MSG_VI_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_I;             // "Va-jerk"
-  LSTR MSG_VJ_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_J;             // "Vb-jerk"
-  LSTR MSG_VK_JERK                        = _UxGT("ジク ヤクドウ mm/s") STR_K;             // "Vc-jerk"
+  LSTR MSG_VN_JERK                        = _UxGT("ジク ヤクドウ mm/s@");                  // "V@-jerk"
   LSTR MSG_A_STEPS                        = STR_A _UxGT("ステップ/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT("ステップ/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT("ステップ/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ステップ/mm");
   LSTR MSG_VE_JERK                        = _UxGT("エクストルーダー ヤクド");          // "Ve-jerk"
   LSTR MSG_VMAX_A                         = _UxGT("サイダイオクリソクド ") STR_A;  // "Vmax A"
   LSTR MSG_VMAX_B                         = _UxGT("サイダイオクリソクド ") STR_B;  // "Vmax B"
   LSTR MSG_VMAX_C                         = _UxGT("サイダイオクリソクド ") STR_C;  // "Vmax C"
-  LSTR MSG_VMAX_I                         = _UxGT("サイダイオクリソクド ") STR_I;  // "Vmax I"
-  LSTR MSG_VMAX_J                         = _UxGT("サイダイオクリソクド ") STR_J;  // "Vmax J"
-  LSTR MSG_VMAX_K                         = _UxGT("サイダイオクリソクド ") STR_K;  // "Vmax K"
-  LSTR MSG_VMAX_E                         = _UxGT("サイダイオクリソクド ") STR_E;  // "Vmax E"
+  LSTR MSG_VMAX_E                         = _UxGT("サイダイオクリソクド E");  // "Vmax E"
   LSTR MSG_VMAX_EN                        = _UxGT("サイダイオクリソクド *");  // "Vmax E1"
   LSTR MSG_VMIN                           = _UxGT("サイショウオクリソクド");           // "Vmin"
   LSTR MSG_VTRAV_MIN                      = _UxGT("サイショウイドウソクド");           // "VTrav min"
@@ -215,13 +211,7 @@ namespace Language_jp_kana {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("セッテイサイコウオン");              // "Max Temp"
   LSTR MSG_INFO_PSU                       = _UxGT("デンゲンシュベツ");                // "Power Supply"
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("モータークドウリョク");              // "Drive Strength"
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" DACシュツリョク %");      // "X Driver %"
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" DACシュツリョク %");      // "Y Driver %"
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" DACシュツリョク %");      // "Z Driver %"
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" DACシュツリョク %");      // "I Driver %"
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" DACシュツリョク %");      // "J Driver %"
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" DACシュツリョク %");      // "K Driver %"
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E DACシュツリョク %");               // "E Driver %"
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ DACシュツリョク %");               // "@ Driver %"
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("EEPROMヘホゾン");               // "Store memory"
   LSTR MSG_FILAMENT_CHANGE_HEADER_PAUSE   = _UxGT("イチジテイシ");
   LSTR MSG_FILAMENT_CHANGE_OPTION_RESUME  = _UxGT("プリントサイカイ");                // "Resume print"
@@ -249,7 +239,7 @@ namespace Language_jp_kana {
   LSTR MSG_YES                            = _UxGT("ハイ");
   LSTR MSG_NO                             = _UxGT("イイエ");
   LSTR MSG_BACK                           = _UxGT("モドリ");
-  LSTR MSG_VELOCITY                       = _UxGT("ソクド");
+  LSTR MSG_MAX_SPEED                      = _UxGT("ソクド");
   LSTR MSG_STEPS_PER_MM                   = _UxGT("ステップ/mm");
   LSTR MSG_CUSTOM_COMMANDS                = _UxGT("ユーザーコマンド");
   LSTR MSG_PRINT_PAUSED                   = _UxGT("プリントガイチジテイシサレマシタ");
diff --git a/Marlin/src/lcd/language/language_nl.h b/Marlin/src/lcd/language/language_nl.h
index 29a8a1fdc8d..6b308ba48ba 100644
--- a/Marlin/src/lcd/language/language_nl.h
+++ b/Marlin/src/lcd/language/language_nl.h
@@ -86,7 +86,7 @@ namespace Language_nl {
   LSTR MSG_MOVE_Z                         = _UxGT("Verplaats Z");
   LSTR MSG_MOVE_E                         = _UxGT("Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Extruder *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Verplaats %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Verplaats $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Verplaats 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Verplaats 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Verplaats 10mm");
@@ -157,6 +157,7 @@ namespace Language_nl {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystap X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystap Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystap Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystap @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop afbr.");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Voorverw. fout");
   LSTR MSG_ERR_REDUNDANT_TEMP             = _UxGT("Redun. temp fout");
diff --git a/Marlin/src/lcd/language/language_pl.h b/Marlin/src/lcd/language/language_pl.h
index 8bd7d2d3015..630f94ab12d 100644
--- a/Marlin/src/lcd/language/language_pl.h
+++ b/Marlin/src/lcd/language/language_pl.h
@@ -27,10 +27,9 @@
  * LCD Menu Messages
  * See also https://marlinfw.org/docs/development/lcd_language.html
  *
- * Substitutions are applied for the following characters when used
- * in menu items that call lcd_put_u8str_ind_P with an index:
+ * Substitutions are applied for the following characters when used in menu items titles:
  *
- *   $ displays an inserted C-string
+ *   $ displays an inserted string
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
@@ -239,7 +238,7 @@ namespace Language_pl {
   LSTR MSG_MOVE_E                         = _UxGT("Ekstruzja (os E)");
   LSTR MSG_MOVE_EN                        = _UxGT("Ekstruzja (os E) *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Dysza za zimna");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Przesuń co %s mm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Przesuń co $ mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Przesuń co .1 mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Przesuń co 1 mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Przesuń co 10 mm");
@@ -276,11 +275,9 @@ namespace Language_pl {
   LSTR MSG_VA_JERK                        = _UxGT("Zryw V") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("Zryw V") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("Zryw V") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("Zryw V") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("Zryw V") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("Zryw V") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("Zryw V@");
   LSTR MSG_VE_JERK                        = _UxGT("Zryw Ve");
-  LSTR MSG_VELOCITY                       = _UxGT("Prędkość (V)");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Prędkość (V)");
 
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vskok min");
   LSTR MSG_ACCELERATION                   = _UxGT("Przyspieszenie (A)");
@@ -292,9 +289,7 @@ namespace Language_pl {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" kroki/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" kroki/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" kroki/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" kroki/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" kroki/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" kroki/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ kroki/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E kroki/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* kroki/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -445,13 +440,7 @@ namespace Language_pl {
 
   LSTR MSG_INFO_PSU                       = _UxGT("Zasilacz");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Siła silnika");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Siła %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Siła %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Siła %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC BŁĄD POŁĄCZENIA");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Zapisz DAC EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("ZMIEŃ FILAMENT");
diff --git a/Marlin/src/lcd/language/language_pt.h b/Marlin/src/lcd/language/language_pt.h
index 2366142f062..69df8bdf542 100644
--- a/Marlin/src/lcd/language/language_pt.h
+++ b/Marlin/src/lcd/language/language_pt.h
@@ -80,7 +80,7 @@ namespace Language_pt {
   LSTR MSG_MOVE_Z                         = _UxGT("Mover Z");
   LSTR MSG_MOVE_E                         = _UxGT("Mover Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Mover Extrusor *");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mover 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mover 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mover 10mm");
@@ -104,9 +104,7 @@ namespace Language_pt {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" passo/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" passo/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" passo/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" passo/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" passo/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" passo/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ passo/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E passo/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* passo/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
diff --git a/Marlin/src/lcd/language/language_pt_br.h b/Marlin/src/lcd/language/language_pt_br.h
index 5e3e33b3762..5b73d6df6de 100644
--- a/Marlin/src/lcd/language/language_pt_br.h
+++ b/Marlin/src/lcd/language/language_pt_br.h
@@ -212,7 +212,7 @@ namespace Language_pt_br {
   LSTR MSG_MOVE_E                         = _UxGT("Mover Extrusor");
   LSTR MSG_MOVE_EN                        = _UxGT("Mover Extrusor *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Extrus. mto fria");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Mover $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Mover 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Mover 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Mover 10mm");
@@ -242,12 +242,10 @@ namespace Language_pt_br {
   LSTR MSG_VA_JERK                        = _UxGT("arrancada V") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("arrancada V") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("arrancada V") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("arrancada V") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("arrancada V") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("arrancada V") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("arrancada V@");
   LSTR MSG_VE_JERK                        = _UxGT("arrancada VE");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Desv. Junção");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocidade");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Velocidade");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VDeslocamento min");
   LSTR MSG_ACCELERATION                   = _UxGT("Aceleração");
   LSTR MSG_A_RETRACT                      = _UxGT("Retrair A");
@@ -256,9 +254,7 @@ namespace Language_pt_br {
   LSTR MSG_A_STEPS                        = _UxGT("Passo ") STR_A _UxGT("/mm");
   LSTR MSG_B_STEPS                        = _UxGT("Passo ") STR_B _UxGT("/mm");
   LSTR MSG_C_STEPS                        = _UxGT("Passo ") STR_C _UxGT("/mm");
-  LSTR MSG_I_STEPS                        = _UxGT("Passo ") STR_I _UxGT("/mm");
-  LSTR MSG_J_STEPS                        = _UxGT("Passo ") STR_J _UxGT("/mm");
-  LSTR MSG_K_STEPS                        = _UxGT("Passo ") STR_K _UxGT("/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("Passo @/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("*/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatura");
@@ -352,6 +348,7 @@ namespace Language_pt_br {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Passinho X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Passinho Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Passinho Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Passinho @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Abortar Fim de Curso");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Aquecimento falhou");
diff --git a/Marlin/src/lcd/language/language_ro.h b/Marlin/src/lcd/language/language_ro.h
index 79421752af0..79160624e7a 100644
--- a/Marlin/src/lcd/language/language_ro.h
+++ b/Marlin/src/lcd/language/language_ro.h
@@ -225,7 +225,7 @@ namespace Language_ro {
   LSTR MSG_MOVE_E                         = _UxGT("Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Extruder *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Capat Prea Rece");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Move %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Move $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Move 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Move 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Move 10mm");
@@ -270,30 +270,24 @@ namespace Language_ro {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT("-Jerk");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT("-Jerk");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT("-Jerk");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT("-Jerk");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT("-Jerk");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT("-Jerk");
+  LSTR MSG_VN_JERK                        = _UxGT("V@-Jerk");
   LSTR MSG_VE_JERK                        = _UxGT("Ve-Jerk");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Junction Dev");
-  LSTR MSG_VELOCITY                       = _UxGT("Velocity");
-  LSTR MSG_VMAX_A                         = _UxGT("Vmax ") STR_A;
-  LSTR MSG_VMAX_B                         = _UxGT("Vmax ") STR_B;
-  LSTR MSG_VMAX_C                         = _UxGT("Vmax ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vmax ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vmax ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vmax ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vmax ") STR_E;
-  LSTR MSG_VMAX_EN                        = _UxGT("Vmax *");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max Speed");
+  LSTR MSG_VMAX_A                         = _UxGT("Max Speed ") STR_A;
+  LSTR MSG_VMAX_B                         = _UxGT("Max Speed ") STR_B;
+  LSTR MSG_VMAX_C                         = _UxGT("Max Speed ") STR_C;
+  LSTR MSG_VMAX_N                         = _UxGT("Max Speed @");
+  LSTR MSG_VMAX_E                         = _UxGT("Max Speed E");
+  LSTR MSG_VMAX_EN                        = _UxGT("Max Speed *");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VTrav Min");
   LSTR MSG_ACCELERATION                   = _UxGT("Acceleration");
   LSTR MSG_AMAX_A                         = _UxGT("Amax ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Amax ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Amax ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Amax ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Amax ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Amax ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Amax ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Amax @");
+  LSTR MSG_AMAX_E                         = _UxGT("Amax E");
   LSTR MSG_AMAX_EN                        = _UxGT("Amax *");
   LSTR MSG_A_RETRACT                      = _UxGT("A-Retract");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-Travel");
@@ -303,11 +297,9 @@ namespace Language_ro {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" steps/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" steps/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" steps/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" steps/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" steps/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" steps/mm");
-  LSTR MSG_E_STEPS                        = _UxGT("Esteps/mm");
-  LSTR MSG_EN_STEPS                       = _UxGT("*steps/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ steps/mm");
+  LSTR MSG_E_STEPS                        = _UxGT("E steps/mm");
+  LSTR MSG_EN_STEPS                       = _UxGT("* steps/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperature");
   LSTR MSG_MOTION                         = _UxGT("Motion");
   LSTR MSG_FILAMENT                       = _UxGT("Filament");
@@ -435,6 +427,7 @@ namespace Language_ro {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop Abort");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Heating Failed");
@@ -503,13 +496,7 @@ namespace Language_ro {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Temperatura Maxima");
   LSTR MSG_INFO_PSU                       = _UxGT("PSU");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Drive Strength");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC CONNECTION ERROR");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM Write");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("FILAMENT CHANGE");
diff --git a/Marlin/src/lcd/language/language_ru.h b/Marlin/src/lcd/language/language_ru.h
index 4b8d4703e45..5f05f1d2beb 100644
--- a/Marlin/src/lcd/language/language_ru.h
+++ b/Marlin/src/lcd/language/language_ru.h
@@ -84,17 +84,11 @@ namespace Language_ru {
     LSTR MSG_HOME_OFFSET_X                  = _UxGT("Смещение дома X");
     LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Смещение дома Y");
     LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Смещение дома Z");
-    LSTR MSG_HOME_OFFSET_I                  = _UxGT("Смещение дома ") STR_I;
-    LSTR MSG_HOME_OFFSET_J                  = _UxGT("Смещение дома ") STR_J;
-    LSTR MSG_HOME_OFFSET_K                  = _UxGT("Смещение дома ") STR_K;
   #else
     LSTR MSG_SET_HOME_OFFSETS               = _UxGT("Установ.смещ.дома");
     LSTR MSG_HOME_OFFSET_X                  = _UxGT("Смещ. дома X");
     LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Смещ. дома Y");
     LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Смещ. дома Z");
-    LSTR MSG_HOME_OFFSET_I                  = _UxGT("Смещ. дома ") STR_I;
-    LSTR MSG_HOME_OFFSET_J                  = _UxGT("Смещ. дома ") STR_J;
-    LSTR MSG_HOME_OFFSET_K                  = _UxGT("Смещ. дома ") STR_K;
   #endif
   LSTR MSG_HOME_OFFSETS_APPLIED             = _UxGT("Смещения применены");
   LSTR MSG_SELECT_ORIGIN                    = _UxGT("Выберите ноль");
@@ -338,9 +332,7 @@ namespace Language_ru {
   LSTR MSG_MOVE_X                           = _UxGT("Движение по X");
   LSTR MSG_MOVE_Y                           = _UxGT("Движение по Y");
   LSTR MSG_MOVE_Z                           = _UxGT("Движение по Z");
-  LSTR MSG_MOVE_I                           = _UxGT("Движение по ") STR_I;
-  LSTR MSG_MOVE_J                           = _UxGT("Движение по ") STR_J;
-  LSTR MSG_MOVE_K                           = _UxGT("Движение по ") STR_K;
+  LSTR MSG_MOVE_N                           = _UxGT("Движение по @");
   LSTR MSG_MOVE_E                           = _UxGT("Экструдер");
   LSTR MSG_MOVE_EN                          = _UxGT("Экструдер *");
   LSTR MSG_HOTEND_TOO_COLD                  = _UxGT("Сопло не нагрето");
@@ -401,23 +393,19 @@ namespace Language_ru {
   LSTR MSG_VA_JERK                          = _UxGT("V") STR_A _UxGT("-рывок");
   LSTR MSG_VB_JERK                          = _UxGT("V") STR_B _UxGT("-рывок");
   LSTR MSG_VC_JERK                          = _UxGT("V") STR_C _UxGT("-рывок");
-  LSTR MSG_VI_JERK                          = _UxGT("V") STR_I _UxGT("-рывок");
-  LSTR MSG_VJ_JERK                          = _UxGT("V") STR_J _UxGT("-рывок");
-  LSTR MSG_VK_JERK                          = _UxGT("V") STR_K _UxGT("-рывок");
+  LSTR MSG_VN_JERK                          = _UxGT("V@-рывок");
   LSTR MSG_VE_JERK                          = _UxGT("Ve-рывок");
   #if LCD_WIDTH > 21 || HAS_DWIN_E3V2
     LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Отклонение узла");
   #else
     LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Отклон. узла");
   #endif
-  LSTR MSG_VELOCITY                         = _UxGT("Скорость, мм/с");
+  LSTR MSG_MAX_SPEED                        = _UxGT("Скорость, мм/с");
   LSTR MSG_VMAX_A                           = _UxGT("Скор.макс ") STR_A;
   LSTR MSG_VMAX_B                           = _UxGT("Скор.макс ") STR_B;
   LSTR MSG_VMAX_C                           = _UxGT("Скор.макс ") STR_C;
-  LSTR MSG_VMAX_I                           = _UxGT("Скор.макс ") STR_I;
-  LSTR MSG_VMAX_J                           = _UxGT("Скор.макс ") STR_J;
-  LSTR MSG_VMAX_K                           = _UxGT("Скор.макс ") STR_K;
-  LSTR MSG_VMAX_E                           = _UxGT("Скор.макс ") STR_E;
+  LSTR MSG_VMAX_N                           = _UxGT("Скор.макс @");
+  LSTR MSG_VMAX_E                           = _UxGT("Скор.макс E");
   LSTR MSG_VMAX_EN                          = _UxGT("Скор.макс *");
   LSTR MSG_VMIN                             = _UxGT("Скор.мин");
   LSTR MSG_VTRAV_MIN                        = _UxGT("Перемещение мин");
@@ -425,10 +413,8 @@ namespace Language_ru {
   LSTR MSG_AMAX_A                           = _UxGT("Ускор.макс ") STR_A;
   LSTR MSG_AMAX_B                           = _UxGT("Ускор.макс ") STR_B;
   LSTR MSG_AMAX_C                           = _UxGT("Ускор.макс ") STR_C;
-  LSTR MSG_AMAX_I                           = _UxGT("Ускор.макс ") STR_I;
-  LSTR MSG_AMAX_J                           = _UxGT("Ускор.макс ") STR_J;
-  LSTR MSG_AMAX_K                           = _UxGT("Ускор.макс ") STR_K;
-  LSTR MSG_AMAX_E                           = _UxGT("Ускор.макс ") STR_E;
+  LSTR MSG_AMAX_N                           = _UxGT("Ускор.макс @");
+  LSTR MSG_AMAX_E                           = _UxGT("Ускор.макс E");
   LSTR MSG_AMAX_EN                          = _UxGT("Ускор.макс *");
   LSTR MSG_A_RETRACT                        = _UxGT("Ускор.втягив.");
   LSTR MSG_A_TRAVEL                         = _UxGT("Ускор.путеш.");
@@ -438,9 +424,7 @@ namespace Language_ru {
   LSTR MSG_A_STEPS                          = STR_A _UxGT(" шаг/мм");
   LSTR MSG_B_STEPS                          = STR_B _UxGT(" шаг/мм");
   LSTR MSG_C_STEPS                          = STR_C _UxGT(" шаг/мм");
-  LSTR MSG_I_STEPS                          = STR_I _UxGT(" шаг/мм");
-  LSTR MSG_J_STEPS                          = STR_J _UxGT(" шаг/мм");
-  LSTR MSG_K_STEPS                          = STR_K _UxGT(" шаг/мм");
+  LSTR MSG_N_STEPS                          = _UxGT("@ шаг/мм");
   LSTR MSG_E_STEPS                          = _UxGT("E шаг/мм");
   LSTR MSG_EN_STEPS                         = _UxGT("* шаг/мм");
   LSTR MSG_TEMPERATURE                      = _UxGT("Температура");
@@ -611,9 +595,7 @@ namespace Language_ru {
   LSTR MSG_BABYSTEP_X                       = _UxGT("Микрошаг X");
   LSTR MSG_BABYSTEP_Y                       = _UxGT("Микрошаг Y");
   LSTR MSG_BABYSTEP_Z                       = _UxGT("Микрошаг Z");
-  LSTR MSG_BABYSTEP_I                       = _UxGT("Микрошаг ") STR_I;
-  LSTR MSG_BABYSTEP_J                       = _UxGT("Микрошаг ") STR_J;
-  LSTR MSG_BABYSTEP_K                       = _UxGT("Микрошаг ") STR_K;
+  LSTR MSG_BABYSTEP_N                       = _UxGT("Микрошаг @");
   LSTR MSG_BABYSTEP_TOTAL                   = _UxGT("Сумарно");
   LSTR MSG_ENDSTOP_ABORT                    = _UxGT("Сработал концевик");
   LSTR MSG_HEATING_FAILED_LCD               = _UxGT("Разогрев не удался");
@@ -710,13 +692,7 @@ namespace Language_ru {
   LSTR MSG_INFO_MAX_TEMP                    = _UxGT("Макс. ") LCD_STR_THERMOMETER;
   LSTR MSG_INFO_PSU                         = _UxGT("БП");
   LSTR MSG_DRIVE_STRENGTH                   = _UxGT("Сила привода");
-  LSTR MSG_DAC_PERCENT_A                    = STR_A _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_B                    = STR_B _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_C                    = STR_C _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_I                    = STR_I _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_J                    = STR_J _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_K                    = STR_K _UxGT(" Привод, %");
-  LSTR MSG_DAC_PERCENT_E                    = _UxGT("E Привод, %");
+  LSTR MSG_DAC_PERCENT_N                    = _UxGT("@ Привод, %");
   LSTR MSG_ERROR_TMC                        = _UxGT("СБОЙ СВЯЗИ С TMC");
   LSTR MSG_DAC_EEPROM_WRITE                 = _UxGT("Запись DAC в EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER           = _UxGT("ЗАМЕНА ФИЛАМЕНТА");
diff --git a/Marlin/src/lcd/language/language_sk.h b/Marlin/src/lcd/language/language_sk.h
index 7ba505ede51..124080de0b8 100644
--- a/Marlin/src/lcd/language/language_sk.h
+++ b/Marlin/src/lcd/language/language_sk.h
@@ -31,10 +31,9 @@
  * Translated by Michal Holeš, Farma MaM
  * https://www.facebook.com/farmamam
  *
- * Substitutions are applied for the following characters when used
- * in menu items that call lcd_put_u8str_ind_P with an index:
+ * Substitutions are applied for the following characters when used in menu items titles:
  *
- *   $ displays an inserted C-string
+ *   $ displays an inserted string
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
@@ -98,9 +97,6 @@ namespace Language_sk {
   LSTR MSG_HOME_OFFSET_X                  = _UxGT("X Ofset");
   LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Y Ofset");
   LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Z Ofset");
-  LSTR MSG_HOME_OFFSET_I                  = STR_I _UxGT(" Ofset");
-  LSTR MSG_HOME_OFFSET_J                  = STR_J _UxGT(" Ofset");
-  LSTR MSG_HOME_OFFSET_K                  = STR_K _UxGT(" Ofset");
   LSTR MSG_HOME_OFFSETS_APPLIED           = _UxGT("Ofsety nastavené");
   LSTR MSG_TRAMMING_WIZARD                = _UxGT("Spriev. vyrovn.");
   LSTR MSG_SELECT_ORIGIN                  = _UxGT("Vyberte začiatok");
@@ -281,13 +277,11 @@ namespace Language_sk {
   LSTR MSG_MOVE_X                         = _UxGT("Posunúť X");
   LSTR MSG_MOVE_Y                         = _UxGT("Posunúť Y");
   LSTR MSG_MOVE_Z                         = _UxGT("Posunúť Z");
-  LSTR MSG_MOVE_I                         = _UxGT("Posunúť ") STR_I;
-  LSTR MSG_MOVE_J                         = _UxGT("Posunúť ") STR_J;
-  LSTR MSG_MOVE_K                         = _UxGT("Posunúť ") STR_K;
+  LSTR MSG_MOVE_N                         = _UxGT("Posunúť @");
   LSTR MSG_MOVE_E                         = _UxGT("Extrudér");
   LSTR MSG_MOVE_EN                        = _UxGT("Extrudér *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hotend je studený");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Posunúť o %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Posunúť o $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Posunúť o 0,1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Posunúť o 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Posunúť o 10mm");
@@ -297,12 +291,6 @@ namespace Language_sk {
   LSTR MSG_MOVE_01IN                      = _UxGT("Posunúť o 0,1in");
   LSTR MSG_MOVE_1IN                       = _UxGT("Posunúť o 1,0in");
   LSTR MSG_SPEED                          = _UxGT("Rýchlosť");
-  LSTR MSG_MAXSPEED                       = _UxGT("Max rýchl. (mm/s)");
-  LSTR MSG_MAXSPEED_X                     = _UxGT("Max rýchl. ") STR_A;
-  LSTR MSG_MAXSPEED_Y                     = _UxGT("Max rýchl. ") STR_B;
-  LSTR MSG_MAXSPEED_Z                     = _UxGT("Max rýchl. ") STR_C;
-  LSTR MSG_MAXSPEED_E                     = _UxGT("Max rýchl. ") STR_E;
-  LSTR MSG_MAXSPEED_A                     = _UxGT("Max rýchl. @");
   LSTR MSG_BED_Z                          = _UxGT("Výška podl.");
   LSTR MSG_NOZZLE                         = _UxGT("Tryska");
   LSTR MSG_NOZZLE_N                       = _UxGT("Tryska ~");
@@ -347,30 +335,24 @@ namespace Language_sk {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT("-skok");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT("-skok");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT("-skok");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT("-skok");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT("-skok");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT("-skok");
+  LSTR MSG_VN_JERK                        = _UxGT("V@-skok");
   LSTR MSG_VE_JERK                        = _UxGT("Ve-skok");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Junction Dev");
-  LSTR MSG_VELOCITY                       = _UxGT("Rýchlosť");
-  LSTR MSG_VMAX_A                         = _UxGT("Vmax ") STR_A;
-  LSTR MSG_VMAX_B                         = _UxGT("Vmax ") STR_B;
-  LSTR MSG_VMAX_C                         = _UxGT("Vmax ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vmax ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vmax ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vmax ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vmax ") STR_E;
-  LSTR MSG_VMAX_EN                        = _UxGT("Vmax *");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Max rýchl. (mm/s)");
+  LSTR MSG_VMAX_A                         = _UxGT("Max rýchl. ") STR_A;
+  LSTR MSG_VMAX_B                         = _UxGT("Max rýchl. ") STR_B;
+  LSTR MSG_VMAX_C                         = _UxGT("Max rýchl. ") STR_C;
+  LSTR MSG_VMAX_N                         = _UxGT("Max rýchl. @");
+  LSTR MSG_VMAX_E                         = _UxGT("Max rýchl. E");
+  LSTR MSG_VMAX_EN                        = _UxGT("Max rýchl. *");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VPrej Min");
   LSTR MSG_ACCELERATION                   = _UxGT("Akcelerácia");
   LSTR MSG_AMAX_A                         = _UxGT("Amax ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Amax ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Amax ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Amax ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Amax ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Amax ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Amax ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Amax @");
+  LSTR MSG_AMAX_E                         = _UxGT("Amax E");
   LSTR MSG_AMAX_EN                        = _UxGT("Amax *");
   LSTR MSG_A_RETRACT                      = _UxGT("A-retrakt");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-prejazd");
@@ -380,11 +362,9 @@ namespace Language_sk {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" krokov/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" krokov/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" krokov/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" krokov/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" krokov/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" krokov/mm");
-  LSTR MSG_E_STEPS                        = _UxGT("Ekrokov/mm");
-  LSTR MSG_EN_STEPS                       = _UxGT("*krokov/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ krokov/mm");
+  LSTR MSG_E_STEPS                        = _UxGT("E krokov/mm");
+  LSTR MSG_EN_STEPS                       = _UxGT("* krokov/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Teplota");
   LSTR MSG_MOTION                         = _UxGT("Pohyb");
   LSTR MSG_FILAMENT                       = _UxGT("Filament");
@@ -527,9 +507,7 @@ namespace Language_sk {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Babystep X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Babystep Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Babystep Z");
-  LSTR MSG_BABYSTEP_I                     = _UxGT("Babystep ") STR_I;
-  LSTR MSG_BABYSTEP_J                     = _UxGT("Babystep ") STR_J;
-  LSTR MSG_BABYSTEP_K                     = _UxGT("Babystep ") STR_K;
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Babystep @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Celkom");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Zastavenie Endstop");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Chyba ohrevu");
@@ -624,13 +602,7 @@ namespace Language_sk {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Teplota max");
   LSTR MSG_INFO_PSU                       = _UxGT("Nap. zdroj");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Budenie motorov");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Motor %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Motor %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Motor %");
   LSTR MSG_ERROR_TMC                      = _UxGT("CHYBA KOMUNIKÁ. TMC");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Uložiť do EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("VÝMENA FILAMENTU");
diff --git a/Marlin/src/lcd/language/language_sv.h b/Marlin/src/lcd/language/language_sv.h
index db2196fa46a..6e6d3e11ecd 100644
--- a/Marlin/src/lcd/language/language_sv.h
+++ b/Marlin/src/lcd/language/language_sv.h
@@ -252,7 +252,7 @@ namespace Language_sv {
   LSTR MSG_MOVE_E                         = _UxGT("Extruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Extruder *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Hetände för kall");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("Flytta %smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("Flytta $mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("Flytta 0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("Flytta 1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("Flytta 10mm");
@@ -300,19 +300,15 @@ namespace Language_sv {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT("-Ryck");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT("-Ryck");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT("-Ryck");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT("-Ryck");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT("-Ryck");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT("-Ryck");
+  LSTR MSG_VN_JERK                        = _UxGT("V@-Ryck");
   LSTR MSG_VE_JERK                        = _UxGT("Ve-Ryck");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Knutpunkt Avv");
-  LSTR MSG_VELOCITY                       = _UxGT("Hastighet");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Hastighet");
   LSTR MSG_VMAX_A                         = _UxGT("Vmax ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("Vmax ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Vmax ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vmax ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vmax ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vmax ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vmax ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Vmax @");
+  LSTR MSG_VMAX_E                         = _UxGT("Vmax E");
   LSTR MSG_VMAX_EN                        = _UxGT("Vmax *");
   LSTR MSG_VMIN                           = _UxGT("Vmin");
   LSTR MSG_VTRAV_MIN                      = _UxGT("VTrav Min");
@@ -320,10 +316,8 @@ namespace Language_sv {
   LSTR MSG_AMAX_A                         = _UxGT("Amax ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Amax ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Amax ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Amax ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Amax ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Amax ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Amax ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Amax @");
+  LSTR MSG_AMAX_E                         = _UxGT("Amax E");
   LSTR MSG_AMAX_EN                        = _UxGT("Amax *");
   LSTR MSG_A_RETRACT                      = _UxGT("A-Dra tillbaka");
   LSTR MSG_A_TRAVEL                       = _UxGT("A-Färdas");
@@ -333,9 +327,7 @@ namespace Language_sv {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" Steg/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" Steg/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" Steg/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" Steg/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" Steg/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" Steg/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ Steg/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E Steg/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* Steg/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Temperatur");
@@ -469,6 +461,7 @@ namespace Language_sv {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Småsteg X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Småsteg Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Småsteg Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Småsteg @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Total");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Slutstopp Avbrott");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Värma Misslyckad");
@@ -540,13 +533,7 @@ namespace Language_sv {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Max Temp");
   LSTR MSG_INFO_PSU                       = _UxGT("PSU");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Driv Styrka");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Driver %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Driver %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Driver %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC KOPPLNINGSFEL");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM Skriv");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("TRÅDBYTE");
diff --git a/Marlin/src/lcd/language/language_tr.h b/Marlin/src/lcd/language/language_tr.h
index 0acdd958c32..b981127ed1c 100644
--- a/Marlin/src/lcd/language/language_tr.h
+++ b/Marlin/src/lcd/language/language_tr.h
@@ -228,7 +228,7 @@ namespace Language_tr {
   LSTR MSG_MOVE_E                         = _UxGT("Ekstruder");
   LSTR MSG_MOVE_EN                        = _UxGT("Ekstruder *");
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("Nozul Çok Soğuk");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("%smm");
+  LSTR MSG_MOVE_N_MM                      = _UxGT("$mm");
   LSTR MSG_MOVE_01MM                      = _UxGT("0.1mm");
   LSTR MSG_MOVE_1MM                       = _UxGT("1mm");
   LSTR MSG_MOVE_10MM                      = _UxGT("10mm");
@@ -263,19 +263,15 @@ namespace Language_tr {
   LSTR MSG_VA_JERK                        = _UxGT("V") STR_A _UxGT("-Sarsım");
   LSTR MSG_VB_JERK                        = _UxGT("V") STR_B _UxGT("-Sarsım");
   LSTR MSG_VC_JERK                        = _UxGT("V") STR_C _UxGT("-Sarsım");
-  LSTR MSG_VI_JERK                        = _UxGT("V") STR_I _UxGT("-Sarsım");
-  LSTR MSG_VJ_JERK                        = _UxGT("V") STR_J _UxGT("-Sarsım");
-  LSTR MSG_VK_JERK                        = _UxGT("V") STR_K _UxGT("-Sarsım");
+  LSTR MSG_VN_JERK                        = _UxGT("V@-Sarsım");
   LSTR MSG_VE_JERK                        = _UxGT("Ve-Sarsım");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Jonksiyon Sapması");
-  LSTR MSG_VELOCITY                       = _UxGT("Hız Vektörü");
+  LSTR MSG_MAX_SPEED                      = _UxGT("Hız Vektörü");
   LSTR MSG_VMAX_A                         = _UxGT("HızVektör.max ") STR_A;
   LSTR MSG_VMAX_B                         = _UxGT("HızVektör.max ") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("HızVektör.max ") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("HızVektör.max ") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("HızVektör.max ") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("HızVektör.max ") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("HızVektör.max ") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("HızVektör.max @");
+  LSTR MSG_VMAX_E                         = _UxGT("HızVektör.max E");
   LSTR MSG_VMAX_EN                        = _UxGT("HızVektör.max *");
   LSTR MSG_VMIN                           = _UxGT("HızVektör.min");
   LSTR MSG_VTRAV_MIN                      = _UxGT("HV.gezinme min");
@@ -283,10 +279,8 @@ namespace Language_tr {
   LSTR MSG_AMAX_A                         = _UxGT("Max. ivme ") STR_A;
   LSTR MSG_AMAX_B                         = _UxGT("Max. ivme ") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Max. ivme ") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Max. ivme ") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("Max. ivme ") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Max. ivme ") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Max. ivme ") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Max. ivme @");
+  LSTR MSG_AMAX_E                         = _UxGT("Max. ivme E");
   LSTR MSG_AMAX_EN                        = _UxGT("Max. ivme *");
   LSTR MSG_A_RETRACT                      = _UxGT("Ivme-geri çekme");
   LSTR MSG_A_TRAVEL                       = _UxGT("Ivme-gezinme");
@@ -294,9 +288,7 @@ namespace Language_tr {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" adım/mm");
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" adım/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" adım/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" adım/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" adım/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" adım/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ adım/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E adım/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("* adım/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Sıcaklık");
@@ -406,6 +398,7 @@ namespace Language_tr {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Miniadım X");
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Miniadım Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Miniadım Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Miniadım @");
   LSTR MSG_BABYSTEP_TOTAL                 = _UxGT("Toplam");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Endstop iptal");
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Isınma başarısız");
@@ -473,13 +466,7 @@ namespace Language_tr {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Max Sıc.");
   LSTR MSG_INFO_PSU                       = _UxGT("Güç Kaynağı");
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Sürücü Gücü");
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" Sürücü %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E Sürücü %");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ Sürücü %");
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC BAĞLANTI HATASI");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("DAC EEPROM Yaz");
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("FILAMAN DEGISTIR");
diff --git a/Marlin/src/lcd/language/language_uk.h b/Marlin/src/lcd/language/language_uk.h
index bfb74b9f6e9..3c47ccada91 100644
--- a/Marlin/src/lcd/language/language_uk.h
+++ b/Marlin/src/lcd/language/language_uk.h
@@ -86,17 +86,11 @@ namespace Language_uk {
     LSTR MSG_HOME_OFFSET_X                  = _UxGT("Зміщення дому X");
     LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Зміщення дому Y");
     LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Зміщення дому Z");
-    LSTR MSG_HOME_OFFSET_I                  = _UxGT("Зміщення дому ") STR_I;
-    LSTR MSG_HOME_OFFSET_J                  = _UxGT("Зміщення дому ") STR_J;
-    LSTR MSG_HOME_OFFSET_K                  = _UxGT("Зміщення дому ") STR_K;
   #else
     LSTR MSG_SET_HOME_OFFSETS               = _UxGT("Встан. зміщ. дому");
     LSTR MSG_HOME_OFFSET_X                  = _UxGT("Зміщ. дому X");
     LSTR MSG_HOME_OFFSET_Y                  = _UxGT("Зміщ. дому Y");
     LSTR MSG_HOME_OFFSET_Z                  = _UxGT("Зміщ. дому Z");
-    LSTR MSG_HOME_OFFSET_I                  = _UxGT("Зміщ. дому ") STR_I;
-    LSTR MSG_HOME_OFFSET_J                  = _UxGT("Зміщ. дому ") STR_J;
-    LSTR MSG_HOME_OFFSET_K                  = _UxGT("Зміщ. дому ") STR_K;
   #endif
   LSTR MSG_HOME_OFFSETS_APPLIED             = _UxGT("Зміщення прийняті");
   LSTR MSG_SELECT_ORIGIN                    = _UxGT("Оберіть нуль");
@@ -339,9 +333,7 @@ namespace Language_uk {
   LSTR MSG_MOVE_X                           = _UxGT("Рух по X");
   LSTR MSG_MOVE_Y                           = _UxGT("Рух по Y");
   LSTR MSG_MOVE_Z                           = _UxGT("Рух по Z");
-  LSTR MSG_MOVE_I                           = _UxGT("Рух по ") STR_I;
-  LSTR MSG_MOVE_J                           = _UxGT("Рух по ") STR_J;
-  LSTR MSG_MOVE_K                           = _UxGT("Рух по ") STR_K;
+  LSTR MSG_MOVE_N                           = _UxGT("Рух по @");
   LSTR MSG_MOVE_E                           = _UxGT("Екструдер");
   LSTR MSG_MOVE_EN                          = _UxGT("Екструдер *");
   LSTR MSG_HOTEND_TOO_COLD                  = _UxGT("Сопло дуже холодне");
@@ -406,23 +398,19 @@ namespace Language_uk {
   LSTR MSG_VA_JERK                          = _UxGT("V") STR_A _UxGT("-ривок");
   LSTR MSG_VB_JERK                          = _UxGT("V") STR_B _UxGT("-ривок");
   LSTR MSG_VC_JERK                          = _UxGT("V") STR_C _UxGT("-ривок");
-  LSTR MSG_VI_JERK                          = _UxGT("V") STR_I _UxGT("-ривок");
-  LSTR MSG_VJ_JERK                          = _UxGT("V") STR_J _UxGT("-ривок");
-  LSTR MSG_VK_JERK                          = _UxGT("V") STR_K _UxGT("-ривок");
+  LSTR MSG_VN_JERK                          = _UxGT("V@-ривок");
   LSTR MSG_VE_JERK                          = _UxGT("Ve-ривок");
   #if LCD_WIDTH > 21 || HAS_DWIN_E3V2
     LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Відхилення вузла");
   #else
     LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Відхил.вузла");
   #endif
-  LSTR MSG_VELOCITY                         = _UxGT("Швидкість, мм/с");
+  LSTR MSG_MAX_SPEED                        = _UxGT("Швидкість, мм/с");
   LSTR MSG_VMAX_A                           = _UxGT("Швидк.макс ") STR_A;
   LSTR MSG_VMAX_B                           = _UxGT("Швидк.макс ") STR_B;
   LSTR MSG_VMAX_C                           = _UxGT("Швидк.макс ") STR_C;
-  LSTR MSG_VMAX_I                           = _UxGT("Швидк.макс ") STR_I;
-  LSTR MSG_VMAX_J                           = _UxGT("Швидк.макс ") STR_J;
-  LSTR MSG_VMAX_K                           = _UxGT("Швидк.макс ") STR_K;
-  LSTR MSG_VMAX_E                           = _UxGT("Швидк.макс ") STR_E;
+  LSTR MSG_VMAX_N                           = _UxGT("Швидк.макс @");
+  LSTR MSG_VMAX_E                           = _UxGT("Швидк.макс E");
   LSTR MSG_VMAX_EN                          = _UxGT("Швидк.макс *");
   LSTR MSG_VMIN                             = _UxGT("Швидк. мін");
   #if LCD_WIDTH > 21 || HAS_DWIN_E3V2
@@ -434,10 +422,8 @@ namespace Language_uk {
   LSTR MSG_AMAX_A                           = _UxGT("Приск.макс ") STR_A;
   LSTR MSG_AMAX_B                           = _UxGT("Приск.макс ") STR_B;
   LSTR MSG_AMAX_C                           = _UxGT("Приск.макс ") STR_C;
-  LSTR MSG_AMAX_I                           = _UxGT("Приск.макс ") STR_I;
-  LSTR MSG_AMAX_J                           = _UxGT("Приск.макс ") STR_J;
-  LSTR MSG_AMAX_K                           = _UxGT("Приск.макс ") STR_K;
-  LSTR MSG_AMAX_E                           = _UxGT("Приск.макс ") STR_E;
+  LSTR MSG_AMAX_N                           = _UxGT("Приск.макс @");
+  LSTR MSG_AMAX_E                           = _UxGT("Приск.макс E");
   LSTR MSG_AMAX_EN                          = _UxGT("Приск.макс *");
   LSTR MSG_A_RETRACT                        = _UxGT("Приск.втягув.");
   LSTR MSG_A_TRAVEL                         = _UxGT("Приск.переміщ.");
@@ -447,9 +433,7 @@ namespace Language_uk {
   LSTR MSG_A_STEPS                          = STR_A _UxGT(" кроків/мм");
   LSTR MSG_B_STEPS                          = STR_B _UxGT(" кроків/мм");
   LSTR MSG_C_STEPS                          = STR_C _UxGT(" кроків/мм");
-  LSTR MSG_I_STEPS                          = STR_I _UxGT(" кроків/мм");
-  LSTR MSG_J_STEPS                          = STR_J _UxGT(" кроків/мм");
-  LSTR MSG_K_STEPS                          = STR_K _UxGT(" кроків/мм");
+  LSTR MSG_N_STEPS                          = _UxGT("@ кроків/мм");
   LSTR MSG_E_STEPS                          = _UxGT("E кроків/мм");
   LSTR MSG_EN_STEPS                         = _UxGT("* кроків/мм");
   LSTR MSG_TEMPERATURE                      = _UxGT("Температура");
@@ -624,9 +608,7 @@ namespace Language_uk {
   LSTR MSG_BABYSTEP_X                       = _UxGT("Мікрокрок X");
   LSTR MSG_BABYSTEP_Y                       = _UxGT("Мікрокрок Y");
   LSTR MSG_BABYSTEP_Z                       = _UxGT("Мікрокрок Z");
-  LSTR MSG_BABYSTEP_I                       = _UxGT("Мікрокрок ") STR_I;
-  LSTR MSG_BABYSTEP_J                       = _UxGT("Мікрокрок ") STR_J;
-  LSTR MSG_BABYSTEP_K                       = _UxGT("Мікрокрок ") STR_K;
+  LSTR MSG_BABYSTEP_N                       = _UxGT("Мікрокрок @");
   LSTR MSG_BABYSTEP_TOTAL                   = _UxGT("Сумарно");
   LSTR MSG_ENDSTOP_ABORT                    = _UxGT("Кінцевик спрацював");
   LSTR MSG_HEATING_FAILED_LCD               = _UxGT("Збій нагріву");
@@ -749,13 +731,7 @@ namespace Language_uk {
   LSTR MSG_INFO_MAX_TEMP                    = _UxGT("Макс. ") LCD_STR_THERMOMETER;
   LSTR MSG_INFO_PSU                         = _UxGT("Блок жив-ня");
   LSTR MSG_DRIVE_STRENGTH                   = _UxGT("Сила мотору");
-  LSTR MSG_DAC_PERCENT_A                    = _UxGT("Драйвер ") STR_A _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_B                    = _UxGT("Драйвер ") STR_B _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_C                    = _UxGT("Драйвер ") STR_C _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_I                    = _UxGT("Драйвер ") STR_I _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_J                    = _UxGT("Драйвер ") STR_J _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_K                    = _UxGT("Драйвер ") STR_K _UxGT(", %");
-  LSTR MSG_DAC_PERCENT_E                    = _UxGT("Драйвер E, %");
+  LSTR MSG_DAC_PERCENT_N                    = _UxGT("Драйвер @, %");
   LSTR MSG_ERROR_TMC                        = _UxGT("ЗБІЙ ЗВ'ЯЗКУ З TMC");
   LSTR MSG_DAC_EEPROM_WRITE                 = _UxGT("Запис ЦАП у EEPROM");
   LSTR MSG_FILAMENT_CHANGE_HEADER           = _UxGT("ЗАМІНА ПРУТКА");
diff --git a/Marlin/src/lcd/language/language_vi.h b/Marlin/src/lcd/language/language_vi.h
index da9e1fc0301..f963e3e346b 100644
--- a/Marlin/src/lcd/language/language_vi.h
+++ b/Marlin/src/lcd/language/language_vi.h
@@ -230,19 +230,15 @@ namespace Language_vi {
   LSTR MSG_VA_JERK                        = _UxGT("Giật-V") STR_A;
   LSTR MSG_VB_JERK                        = _UxGT("Giật-V") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("Giật-V") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("Giật-V") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("Giật-V") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("Giật-V") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("Giật-V@");
   LSTR MSG_VE_JERK                        = _UxGT("Giật-Ve");
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("Độ Lệch Chỗ Giao");                    // Junction Dev
-  LSTR MSG_VELOCITY                       = _UxGT("Vận tốc");                              // velocity
+  LSTR MSG_MAX_SPEED                      = _UxGT("Vận tốc");                              // velocity
   LSTR MSG_VMAX_A                         = _UxGT("Vđa") STR_A;                        // Vmax
   LSTR MSG_VMAX_B                         = _UxGT("Vđa") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("Vđa") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("Vđa") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("Vđa") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("Vđa") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("Vđa") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("Vđa@");
+  LSTR MSG_VMAX_E                         = _UxGT("VđaE");
   LSTR MSG_VMAX_EN                        = _UxGT("Vđa *");
   LSTR MSG_VMIN                           = _UxGT("Vthiểu");                               // Vmin
   LSTR MSG_VTRAV_MIN                      = _UxGT("Vchuyển thiểu");                        // VTrav min
@@ -250,10 +246,8 @@ namespace Language_vi {
   LSTR MSG_AMAX_A                         = _UxGT("Tăng tốc ca") STR_A;                // Amax
   LSTR MSG_AMAX_B                         = _UxGT("Tăng tốc ca") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("Tăng tốc ca") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("Tăng tốc ca") STR_I;                // Amax
-  LSTR MSG_AMAX_J                         = _UxGT("Tăng tốc ca") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("Tăng tốc ca") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("Tăng tốc ca") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("Tăng tốc ca@");
+  LSTR MSG_AMAX_E                         = _UxGT("Tăng tốc caE");
   LSTR MSG_AMAX_EN                        = _UxGT("Tăng tốc ca *");
   LSTR MSG_A_RETRACT                      = _UxGT("TT-Rút");                               // A-retract
   LSTR MSG_A_TRAVEL                       = _UxGT("TT-Chuyển");                            // A-travel
@@ -261,9 +255,7 @@ namespace Language_vi {
   LSTR MSG_A_STEPS                        = _UxGT("Bước") STR_A _UxGT("/mm");          // Steps/mm
   LSTR MSG_B_STEPS                        = _UxGT("Bước") STR_B _UxGT("/mm");
   LSTR MSG_C_STEPS                        = _UxGT("Bước") STR_C _UxGT("/mm");
-  LSTR MSG_I_STEPS                        = _UxGT("Bước") STR_I _UxGT("/mm");          // Steps/mm
-  LSTR MSG_J_STEPS                        = _UxGT("Bước") STR_J _UxGT("/mm");
-  LSTR MSG_K_STEPS                        = _UxGT("Bước") STR_K _UxGT("/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("Bước@/mm");
   LSTR MSG_E_STEPS                        = _UxGT("BướcE/mm");
   LSTR MSG_EN_STEPS                       = _UxGT("Bước */mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("Nhiệt độ");                             // Temperature
@@ -339,6 +331,7 @@ namespace Language_vi {
   LSTR MSG_BABYSTEP_X                     = _UxGT("Nhít X");                               // Babystep X
   LSTR MSG_BABYSTEP_Y                     = _UxGT("Nhít Y");
   LSTR MSG_BABYSTEP_Z                     = _UxGT("Nhít Z");
+  LSTR MSG_BABYSTEP_N                     = _UxGT("Nhít @");
   LSTR MSG_ENDSTOP_ABORT                  = _UxGT("Hủy bỏ công tắc");                      // Endstop abort
   LSTR MSG_HEATING_FAILED_LCD             = _UxGT("Sưởi đầu phun không thành công");       // Heating failed
   LSTR MSG_ERR_REDUNDANT_TEMP             = _UxGT("Điều sai: nhiệt độ dư");                // Err: REDUNDANT TEMP
@@ -399,13 +392,7 @@ namespace Language_vi {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("Nhiệt độ tối đa");                      // Max temp
   LSTR MSG_INFO_PSU                       = _UxGT("Bộ nguồn");                             // PSU
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("Sức mạnh ổ đĩa");                       // Drive Strength
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" % trình điều khiển");        // X Driver %
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" % trình điều khiển");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" % trình điều khiển");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" % trình điều khiển");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" % trình điều khiển");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" % trình điều khiển");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E % trình điều khiển");
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ % trình điều khiển");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("Ghi DAC EEPROM");                       // DAC EEPROM Write
   LSTR MSG_FILAMENT_CHANGE_HEADER_PAUSE   = _UxGT("In tạm dừng");                          // PRINT PAUSED
   LSTR MSG_FILAMENT_CHANGE_HEADER_LOAD    = _UxGT("Nạp dây nhựa");
diff --git a/Marlin/src/lcd/language/language_zh_CN.h b/Marlin/src/lcd/language/language_zh_CN.h
index f2d348b3965..a4816ff899c 100644
--- a/Marlin/src/lcd/language/language_zh_CN.h
+++ b/Marlin/src/lcd/language/language_zh_CN.h
@@ -225,7 +225,7 @@ namespace Language_zh_CN {
   LSTR MSG_MOVE_E                         = _UxGT("挤出机");     // "Extruder"
   LSTR MSG_MOVE_EN                        = _UxGT("挤出机 *");     // "Extruder"
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("热端太冷");
-  LSTR MSG_MOVE_N_MM                      = _UxGT("移动 %s mm");     // "Move 0.025mm"
+  LSTR MSG_MOVE_N_MM                      = _UxGT("移动 $ mm");      // "Move 0.025mm"
   LSTR MSG_MOVE_01MM                      = _UxGT("移动 0.1 mm");     // "Move 0.1mm"
   LSTR MSG_MOVE_1MM                       = _UxGT("移动 1 mm");     // "Move 1mm"
   LSTR MSG_MOVE_10MM                      = _UxGT("移动 10 mm");     // "Move 10mm"
@@ -270,19 +270,15 @@ namespace Language_zh_CN {
   LSTR MSG_VA_JERK                        = _UxGT("轴抖动速率") STR_A;     // "Va-jerk"
   LSTR MSG_VB_JERK                        = _UxGT("轴抖动速率") STR_B;     // "Vb-jerk"
   LSTR MSG_VC_JERK                        = _UxGT("轴抖动速率") STR_C;     // "Vc-jerk"
-  LSTR MSG_VI_JERK                        = _UxGT("轴抖动速率") STR_I;     // "Vi-jerk"
-  LSTR MSG_VJ_JERK                        = _UxGT("轴抖动速率") STR_J;     // "Vj-jerk"
-  LSTR MSG_VK_JERK                        = _UxGT("轴抖动速率") STR_K;     // "Vk-jerk"
+  LSTR MSG_VN_JERK                        = _UxGT("轴抖动速率@");          // "V@-jerk"
   LSTR MSG_VE_JERK                        = _UxGT("挤出机抖动速率");     // "Ve-jerk"
   LSTR MSG_JUNCTION_DEVIATION             = _UxGT("接点差");
-  LSTR MSG_VELOCITY                       = _UxGT("速度");     // "Velocity"
+  LSTR MSG_MAX_SPEED                      = _UxGT("速度");     // "Velocity"
   LSTR MSG_VMAX_A                         = _UxGT("最大进料速率") STR_A;     // "Vmax " max_feedrate_mm_s
   LSTR MSG_VMAX_B                         = _UxGT("最大进料速率") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("最大进料速率") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("最大进料速率") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("最大进料速率") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("最大进料速率") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("最大进料速率") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("最大进料速率@");
+  LSTR MSG_VMAX_E                         = _UxGT("最大进料速率E");
   LSTR MSG_VMAX_EN                        = _UxGT("最大进料速率 *");
   LSTR MSG_VMIN                           = _UxGT("最小进料速率");     // "Vmin"  min_feedrate_mm_s
   LSTR MSG_VTRAV_MIN                      = _UxGT("最小移动速率");     // "VTrav min" min_travel_feedrate_mm_s, (target) speed of the move
@@ -290,10 +286,8 @@ namespace Language_zh_CN {
   LSTR MSG_AMAX_A                         = _UxGT("最大打印加速度") STR_A;     // "Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves
   LSTR MSG_AMAX_B                         = _UxGT("最大打印加速度") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("最大打印加速度") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("最大打印加速度") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("最大打印加速度") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("最大打印加速度") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("最大打印加速度") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("最大打印加速度@");
+  LSTR MSG_AMAX_E                         = _UxGT("最大打印加速度E");
   LSTR MSG_AMAX_EN                        = _UxGT("最大打印加速度 *");
   LSTR MSG_A_RETRACT                      = _UxGT("收进加速度");     // "A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts
   LSTR MSG_A_TRAVEL                       = _UxGT("非打印移动加速度");     // "A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves
@@ -303,9 +297,7 @@ namespace Language_zh_CN {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" 步数/mm");     // "Asteps/mm"
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" 步数/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" 步数/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" 步数/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" 步数/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" 步数/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ 步数/mm");
   LSTR MSG_E_STEPS                        = _UxGT("E 步数/mm");     // "Esteps/mm"
   LSTR MSG_EN_STEPS                       = _UxGT("* 步数/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("温度");     // "Temperature"
@@ -507,13 +499,7 @@ namespace Language_zh_CN {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("最高温度");     // "Max Temp"
   LSTR MSG_INFO_PSU                       = _UxGT("电源供应");     // "Power Supply"
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("驱动力度");     // "Drive Strength"
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" 驱动 %");     // "X Driver %"
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" 驱动 %");
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" 驱动 %");
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" 驱动 %");
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" 驱动 %");
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" 驱动 %");
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E 驱动 %");     // "E Driver %"
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ 驱动 %");     // "E Driver %"
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC 连接错误");
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("保存驱动设置");     // "DAC EEPROM Write"
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("更换料");
diff --git a/Marlin/src/lcd/language/language_zh_TW.h b/Marlin/src/lcd/language/language_zh_TW.h
index 3c0acd5fa87..5f7c85c8383 100644
--- a/Marlin/src/lcd/language/language_zh_TW.h
+++ b/Marlin/src/lcd/language/language_zh_TW.h
@@ -221,7 +221,7 @@ namespace Language_zh_TW {
   LSTR MSG_MOVE_E                         = _UxGT("擠出機");     // "Extruder"
   LSTR MSG_MOVE_EN                        = _UxGT("擠出機 *");       // "Extruder *"
   LSTR MSG_HOTEND_TOO_COLD                = _UxGT("噴嘴溫度不夠");   // "Hotend too cold"
-  LSTR MSG_MOVE_N_MM                      = _UxGT("移動 %s mm");     // "Move 0.025mm"
+  LSTR MSG_MOVE_N_MM                      = _UxGT("移動 $ mm");      // "Move 0.025mm"
   LSTR MSG_MOVE_01MM                      = _UxGT("移動 0.1 mm");    // "Move 0.1mm"
   LSTR MSG_MOVE_1MM                       = _UxGT("移動 1 mm");      // "Move 1mm"
   LSTR MSG_MOVE_10MM                      = _UxGT("移動 10 mm");     // "Move 10mm"
@@ -254,19 +254,15 @@ namespace Language_zh_TW {
   LSTR MSG_VA_JERK                        = _UxGT("軸抖動速率") STR_A;     // "Va-jerk"
   LSTR MSG_VB_JERK                        = _UxGT("軸抖動速率") STR_B;
   LSTR MSG_VC_JERK                        = _UxGT("軸抖動速率") STR_C;
-  LSTR MSG_VI_JERK                        = _UxGT("軸抖動速率") STR_I;
-  LSTR MSG_VJ_JERK                        = _UxGT("軸抖動速率") STR_J;
-  LSTR MSG_VK_JERK                        = _UxGT("軸抖動速率") STR_K;
+  LSTR MSG_VN_JERK                        = _UxGT("軸抖動速率@");
   LSTR MSG_VE_JERK                        = _UxGT("擠出機抖動速率");
 
-  LSTR MSG_VELOCITY                       = _UxGT("速度");     // "Velocity"
+  LSTR MSG_MAX_SPEED                      = _UxGT("速度");     // "Velocity"
   LSTR MSG_VMAX_A                         = _UxGT("最大進料速率") STR_A;     // "Vmax " max_feedrate_mm_s
   LSTR MSG_VMAX_B                         = _UxGT("最大進料速率") STR_B;
   LSTR MSG_VMAX_C                         = _UxGT("最大進料速率") STR_C;
-  LSTR MSG_VMAX_I                         = _UxGT("最大進料速率") STR_I;
-  LSTR MSG_VMAX_J                         = _UxGT("最大進料速率") STR_J;
-  LSTR MSG_VMAX_K                         = _UxGT("最大進料速率") STR_K;
-  LSTR MSG_VMAX_E                         = _UxGT("最大進料速率") STR_E;
+  LSTR MSG_VMAX_N                         = _UxGT("最大進料速率@");
+  LSTR MSG_VMAX_E                         = _UxGT("最大進料速率E");
   LSTR MSG_VMAX_EN                        = _UxGT("最大進料速率 *");     // "Vmax " max_feedrate_mm_s
   LSTR MSG_VMIN                           = _UxGT("最小進料速率");     // "Vmin"  min_feedrate_mm_s
   LSTR MSG_VTRAV_MIN                      = _UxGT("最小移動速率");     // "VTrav min" min_travel_feedrate_mm_s, (target) speed of the move
@@ -274,10 +270,8 @@ namespace Language_zh_TW {
   LSTR MSG_AMAX_A                         = _UxGT("最大列印加速度") STR_A;     // "Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves
   LSTR MSG_AMAX_B                         = _UxGT("最大列印加速度") STR_B;
   LSTR MSG_AMAX_C                         = _UxGT("最大列印加速度") STR_C;
-  LSTR MSG_AMAX_I                         = _UxGT("最大列印加速度") STR_I;
-  LSTR MSG_AMAX_J                         = _UxGT("最大列印加速度") STR_J;
-  LSTR MSG_AMAX_K                         = _UxGT("最大列印加速度") STR_K;
-  LSTR MSG_AMAX_E                         = _UxGT("最大列印加速度") STR_E;
+  LSTR MSG_AMAX_N                         = _UxGT("最大列印加速度@");
+  LSTR MSG_AMAX_E                         = _UxGT("最大列印加速度E");
   LSTR MSG_AMAX_EN                        = _UxGT("最大列印加速度 *");     // "Amax " max_acceleration_mm_per_s2, acceleration in units/s^2 for print moves
   LSTR MSG_A_RETRACT                      = _UxGT("回縮加速度");     // "A-retract" retract_acceleration, E acceleration in mm/s^2 for retracts
   LSTR MSG_A_TRAVEL                       = _UxGT("非列印移動加速度");     // "A-travel" travel_acceleration, X, Y, Z acceleration in mm/s^2 for travel (non printing) moves
@@ -285,9 +279,7 @@ namespace Language_zh_TW {
   LSTR MSG_A_STEPS                        = STR_A _UxGT(" 軸步數/mm");     // "Asteps/mm" axis_steps_per_mm, axis steps-per-unit G92
   LSTR MSG_B_STEPS                        = STR_B _UxGT(" 軸步數/mm");
   LSTR MSG_C_STEPS                        = STR_C _UxGT(" 軸步數/mm");
-  LSTR MSG_I_STEPS                        = STR_I _UxGT(" 軸步數/mm");
-  LSTR MSG_J_STEPS                        = STR_J _UxGT(" 軸步數/mm");
-  LSTR MSG_K_STEPS                        = STR_K _UxGT(" 軸步數/mm");
+  LSTR MSG_N_STEPS                        = _UxGT("@ 軸步數/mm");
   LSTR MSG_E_STEPS                        = _UxGT("擠出機步數/mm");     // "Esteps/mm"
   LSTR MSG_EN_STEPS                       = _UxGT("擠出機~步數/mm");
   LSTR MSG_TEMPERATURE                    = _UxGT("溫度");     // "Temperature"
@@ -454,13 +446,7 @@ namespace Language_zh_TW {
   LSTR MSG_INFO_MAX_TEMP                  = _UxGT("最高溫度");     // "Max Temp"
   LSTR MSG_INFO_PSU                       = _UxGT("電源供應");     // "Power Supply"
   LSTR MSG_DRIVE_STRENGTH                 = _UxGT("驅動力度");     // "Drive Strength"
-  LSTR MSG_DAC_PERCENT_A                  = STR_A _UxGT(" 驅動 %");    // X Driver %
-  LSTR MSG_DAC_PERCENT_B                  = STR_B _UxGT(" 驅動 %");    // Y Driver %
-  LSTR MSG_DAC_PERCENT_C                  = STR_C _UxGT(" 驅動 %");    // Z Driver %
-  LSTR MSG_DAC_PERCENT_I                  = STR_I _UxGT(" 驅動 %");    // I Driver %
-  LSTR MSG_DAC_PERCENT_J                  = STR_J _UxGT(" 驅動 %");    // J Driver %
-  LSTR MSG_DAC_PERCENT_K                  = STR_K _UxGT(" 驅動 %");    // K Driver %
-  LSTR MSG_DAC_PERCENT_E                  = _UxGT("E 驅動 %");    //E Driver %
+  LSTR MSG_DAC_PERCENT_N                  = _UxGT("@ 驅動 %");    //E Driver %
   LSTR MSG_ERROR_TMC                      = _UxGT("TMC連接錯誤");   // "TMC CONNECTION ERROR"
   LSTR MSG_DAC_EEPROM_WRITE               = _UxGT("保存驅動設置");     // "DAC EEPROM Write"
   LSTR MSG_FILAMENT_CHANGE_HEADER         = _UxGT("更換絲料");   // "FILAMENT CHANGE"
diff --git a/Marlin/src/lcd/lcdprint.cpp b/Marlin/src/lcd/lcdprint.cpp
index 8ca0c8ee9e3..69218130699 100644
--- a/Marlin/src/lcd/lcdprint.cpp
+++ b/Marlin/src/lcd/lcdprint.cpp
@@ -32,19 +32,19 @@
 #include "lcdprint.h"
 
 /**
- * lcd_put_u8str_ind_P
+ * lcd_put_u8str_P
  *
- * Print a string with an index substituted within it:
+ * Print a string with optional substitutions:
  *
- *   $ displays the clipped C-string given by the inStr argument
+ *   $ displays the clipped string given by fstr or cstr
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
  *   @ displays an axis name such as XYZUVW, or E for an extruder
  */
-lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
+lcd_uint_t lcd_put_u8str_P(PGM_P const ptpl, const int8_t ind, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
   const uint8_t prop = USE_WIDE_GLYPH ? 2 : 1;
-  uint8_t *p = (uint8_t*)pstr;
+  const uint8_t *p = (uint8_t*)ptpl;
   int8_t n = maxlen;
   while (n > 0) {
     wchar_t ch;
@@ -71,8 +71,11 @@ lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const i
         break;
       }
     }
-    else if (ch == '$' && inStr) {
-      n -= lcd_put_u8str_max_P(inStr, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
+    else if (ch == '$' && fstr) {
+      n -= lcd_put_u8str_max_P(FTOP(fstr), n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
+    }
+    else if (ch == '$' && cstr) {
+      n -= lcd_put_u8str_max(cstr, n * (MENU_FONT_WIDTH)) / (MENU_FONT_WIDTH);
     }
     else if (ch == '@') {
       lcd_put_wchar(axis_codes[ind]);
@@ -90,7 +93,7 @@ lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const i
 int calculateWidth(PGM_P const pstr) {
   if (!USE_WIDE_GLYPH) return utf8_strlen_P(pstr) * MENU_FONT_WIDTH;
   const uint8_t prop = 2;
-  uint8_t *p = (uint8_t*)pstr;
+  const uint8_t *p = (uint8_t*)pstr;
   int n = 0;
 
   do {
diff --git a/Marlin/src/lcd/lcdprint.h b/Marlin/src/lcd/lcdprint.h
index d716d035caf..2eb47c534b0 100644
--- a/Marlin/src/lcd/lcdprint.h
+++ b/Marlin/src/lcd/lcdprint.h
@@ -130,83 +130,167 @@
 
 int lcd_glyph_height();
 
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length);
+/**
+ * @brief Draw a UTF-8 character
+ *
+ * @param utf8_str : the UTF-8 character
+ * @param max_length : the output width limit (in pixels on GLCD)
+ *
+ * @return the output width (in pixels on GLCD)
+ */
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length);
 
 /**
- * @brief Draw a UTF-8 string
+ * @brief Draw a SRAM UTF-8 string
  *
  * @param utf8_str : the UTF-8 string
- * @param max_length : the pixel length of the string allowed (or number of slots in HD44780)
+ * @param max_length : the output width limit (in pixels on GLCD)
  *
- * @return the pixel width
- *
- * Draw a UTF-8 string
+ * @return the output width (in pixels on GLCD)
  */
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length);
+int lcd_put_u8str_max(const char *utf8_str, const pixel_len_t max_length);
 
 /**
- * Set the print baseline position
+ * Change the print cursor position
  */
 void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row);
 
 /**
  * @brief Draw a ROM UTF-8 string
  *
- * @param utf8_pstr : the ROM UTF-8 string
- * @param max_length : the pixel length of the string allowed (or number of slots in HD44780)
+ * @param pstr : the ROM UTF-8 string
+ * @param max_length : the output width limit (in pixels on GLCD)
  *
- * @return the pixel width
- *
- * Draw a ROM UTF-8 string
+ * @return the output width (in pixels on GLCD)
  */
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length);
-inline int lcd_put_u8str_max_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P pstr, const pixel_len_t max_length);
+inline int lcd_put_u8str_max_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P pstr, const pixel_len_t max_length) {
   lcd_moveto(col, row);
-  return lcd_put_u8str_max_P(utf8_pstr, max_length);
+  return lcd_put_u8str_max_P(pstr, max_length);
 }
-inline int lcd_put_u8str_max(const lcd_uint_t col, const lcd_uint_t row, FSTR_P const utf8_fstr, pixel_len_t max_length) {
-  return lcd_put_u8str_max_P(col, row, FTOP(utf8_fstr), max_length);
+inline int lcd_put_u8str_max(const lcd_uint_t col, const lcd_uint_t row, FSTR_P const fstr, const pixel_len_t max_length) {
+  return lcd_put_u8str_max_P(col, row, FTOP(fstr), max_length);
 }
 
+/**
+ * @brief Draw an integer, left-justified
+ *
+ * @param i : the integer
+ */
 void lcd_put_int(const int i);
 inline void lcd_put_int(const lcd_uint_t col, const lcd_uint_t row, const int i) {
   lcd_moveto(col, row);
   lcd_put_int(i);
 }
 
+/**
+ * @brief Draw a ROM UTF-8 string
+ *
+ * @param i : the integer
+ */
 inline int lcd_put_u8str_P(PGM_P const pstr) { return lcd_put_u8str_max_P(pstr, PIXEL_LEN_NOLIMIT); }
 inline int lcd_put_u8str_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P const pstr) {
   lcd_moveto(col, row);
   return lcd_put_u8str_P(pstr);
 }
 
+/**
+ * @brief Draw a ROM UTF-8 F-string
+ *
+ * @param fstr The F-string pointer
+ * @return the output width (in pixels on GLCD)
+ */
 inline int lcd_put_u8str(FSTR_P const fstr) { return lcd_put_u8str_P(FTOP(fstr)); }
 inline int lcd_put_u8str(const lcd_uint_t col, const lcd_uint_t row, FSTR_P const fstr) {
   return lcd_put_u8str_P(col, row, FTOP(fstr));
 }
 
-lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH);
-inline lcd_uint_t lcd_put_u8str_ind_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P const pstr, const int8_t ind, PGM_P const inStr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
+/**
+ * @brief Draw a string with optional substitution
+ * @details Print a string with optional substitutions:
+ *   $ displays the clipped string given by fstr or cstr
+ *   = displays  '0'....'10' for indexes 0 - 10
+ *   ~ displays  '1'....'11' for indexes 0 - 10
+ *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
+ *   @ displays an axis name such as XYZUVW, or E for an extruder
+ *
+ * @param ptpl A ROM string (template)
+ * @param ind An index value to use for = ~ * substitution
+ * @param cstr An SRAM C-string to use for $ substitution
+ * @param fstr A ROM F-string to use for $ substitution
+ * @param maxlen The maximum size of the string (in pixels on GLCD)
+ * @return the output width (in pixels on GLCD)
+ */
+lcd_uint_t lcd_put_u8str_P(PGM_P const ptpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH);
+inline lcd_uint_t lcd_put_u8str_P(const lcd_uint_t col, const lcd_uint_t row, PGM_P const ptpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
   lcd_moveto(col, row);
-  return lcd_put_u8str_ind_P(pstr, ind, inStr, maxlen);
+  return lcd_put_u8str_P(ptpl, ind, cstr, fstr, maxlen);
 }
-inline lcd_uint_t lcd_put_u8str_ind(FSTR_P const fstr, const int8_t ind, FSTR_P const inFstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
-  return lcd_put_u8str_ind_P(FTOP(fstr), ind, FTOP(inFstr), maxlen);
+/**
+ * @brief Draw a ROM UTF-8 F-string with optional substitution
+ * @details (See above)
+ *
+ * @param ftpl A ROM F-string (template)
+ * @param ind An index value to use for = ~ * substitution
+ * @param cstr An SRAM C-string to use for $ substitution
+ * @param fstr A ROM F-string to use for $ substitution
+ * @param maxlen The maximum size of the string (in pixels on GLCD)
+ * @return the output width (in pixels on GLCD)
+ */
+inline lcd_uint_t lcd_put_u8str(FSTR_P const ftpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
+  return lcd_put_u8str_P(FTOP(ftpl), ind, cstr, fstr, maxlen);
 }
-inline lcd_uint_t lcd_put_u8str_ind(const lcd_uint_t col, const lcd_uint_t row, FSTR_P const fstr, const int8_t ind, FSTR_P const inFstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
-  return lcd_put_u8str_ind_P(col, row, FTOP(fstr), ind, FTOP(inFstr), maxlen);
+/**
+ * @param col
+ * @param row
+ */
+inline lcd_uint_t lcd_put_u8str(const lcd_uint_t col, const lcd_uint_t row, FSTR_P const ftpl, const int8_t ind, const char *cstr=nullptr, FSTR_P const fstr=nullptr, const lcd_uint_t maxlen=LCD_WIDTH) {
+  return lcd_put_u8str_P(col, row, FTOP(ftpl), ind, cstr, fstr, maxlen);
 }
 
+/**
+ * @brief Draw a SRAM string with no width limit
+ *
+ * @param str The UTF-8 string
+ * @return the output width (in pixels on GLCD)
+ */
 inline int lcd_put_u8str(const char * const str) { return lcd_put_u8str_max(str, PIXEL_LEN_NOLIMIT); }
+/**
+ * @param col
+ * @param row
+ */
 inline int lcd_put_u8str(const lcd_uint_t col, const lcd_uint_t row, const char * const str) {
   lcd_moveto(col, row);
   return lcd_put_u8str(str);
 }
 
+/**
+ * @brief Draw a UTF-8 character with no width limit
+ *
+ * @param c The wchar to draw
+ * @return the output width (in pixels on GLCD)
+ */
 inline int lcd_put_wchar(const wchar_t c) { return lcd_put_wchar_max(c, PIXEL_LEN_NOLIMIT); }
+/**
+ * @param col
+ * @param row
+ */
 inline int lcd_put_wchar(const lcd_uint_t col, const lcd_uint_t row, const wchar_t c) {
   lcd_moveto(col, row);
   return lcd_put_wchar(c);
 }
 
+/**
+ * @brief Calculate the width of a ROM UTF-8 string (in pixels on GLCD)
+ *
+ * @param pstr The ROM-based UTF-8 string
+ * @return the string width (in pixels on GLCD)
+ */
 int calculateWidth(PGM_P const pstr);
+/**
+ * @brief Calculate the width of a ROM UTF-8 string (in pixels on GLCD)
+ *
+ * @param pstr The ROM-based UTF-8 string
+ * @return the string width (in pixels on GLCD)
+ */
+inline int calculateWidth(FSTR_P const fstr) { return calculateWidth(FTOP(fstr)); }
diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp
index af1286c48b0..0765ef40a91 100644
--- a/Marlin/src/lcd/marlinui.cpp
+++ b/Marlin/src/lcd/marlinui.cpp
@@ -416,10 +416,11 @@ void MarlinUI::init() {
           SETCURSOR(0, row);              // Simulate carriage return
         };
 
-        uint8_t *p = (uint8_t*)string;
+        const uint8_t *p = (uint8_t*)string;
         wchar_t ch;
         if (wordwrap) {
-          uint8_t *wrd = nullptr, c = 0;
+          const uint8_t *wrd = nullptr;
+          uint8_t c = 0;
           // find the end of the part
           for (;;) {
             if (!wrd) wrd = p;            // Get word start /before/ advancing
diff --git a/Marlin/src/lcd/menu/menu.cpp b/Marlin/src/lcd/menu/menu.cpp
index 92be24aa064..4dc1105f78b 100644
--- a/Marlin/src/lcd/menu/menu.cpp
+++ b/Marlin/src/lcd/menu/menu.cpp
@@ -68,9 +68,10 @@ typedef struct {
 menuPosition screen_history[6];
 uint8_t screen_history_depth = 0;
 
-int8_t MenuItemBase::itemIndex;   // Index number for draw and action
-FSTR_P MenuItemBase::itemString;  // A string for substitution
-chimera_t editable;               // Value Editing
+int8_t MenuItemBase::itemIndex;         // Index number for draw and action
+FSTR_P MenuItemBase::itemStringF;       // A string for substitution
+const char *MenuItemBase::itemStringC;
+chimera_t editable;                     // Value Editing
 
 // Menu Edit Items
 FSTR_P       MenuEditItemBase::editLabel;
diff --git a/Marlin/src/lcd/menu/menu.h b/Marlin/src/lcd/menu/menu.h
index fbee2c8501f..2dd6315ad97 100644
--- a/Marlin/src/lcd/menu/menu.h
+++ b/Marlin/src/lcd/menu/menu.h
@@ -53,15 +53,17 @@ class MenuItemBase {
     // Index to interject in the item label and/or for use by its action.
     static int8_t itemIndex;
 
-    // An optional pointer for use in display or by the action
-    static FSTR_P itemString;
+    // Optional pointers for use in display or by the action
+    static FSTR_P itemStringF;
+    static const char* itemStringC;
 
-    // Store the index of the item ahead of use by indexed items
-    FORCE_INLINE static void init(const int8_t ind=0, FSTR_P const fstr=nullptr) { itemIndex = ind; itemString = fstr; }
+    // Store an index and string for later substitution
+    FORCE_INLINE static void init(const int8_t ind=0, FSTR_P const fstr=nullptr) { itemIndex = ind; itemStringF = fstr; itemStringC = nullptr; }
+    FORCE_INLINE static void init(const int8_t ind, const char * const cstr) { itemIndex = ind; itemStringC = cstr; itemStringF = nullptr; }
 
     // Implementation-specific:
     // Draw an item either selected (pre_char) or not (space) with post_char
-    // Menus may set up itemIndex, itemString and pass them to string-building or string-emitting functions
+    // Menus may set up itemIndex, itemStringC/F and pass them to string-building or string-emitting functions
     static void _draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char);
 
     // Draw an item either selected ('>') or not (space) with post_char
@@ -90,8 +92,8 @@ class MenuItem_back : public MenuItemBase {
 // YESNO_ITEM(LABEL,FY,FN,...)
 class MenuItem_confirm : public MenuItemBase {
   public:
-    FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, ...) {
-      _draw(sel, row, fstr, '>', LCD_STR_ARROW_RIGHT[0]);
+    FORCE_INLINE static void draw(const bool sel, const uint8_t row, FSTR_P const ftpl, ...) {
+      _draw(sel, row, ftpl, '>', LCD_STR_ARROW_RIGHT[0]);
     }
     // Implemented for HD44780 and DOGM
     // Draw the prompt, buttons, and state
@@ -170,10 +172,10 @@ class MenuEditItemBase : public MenuItemBase {
   public:
     // Implementation-specific:
     // Draw the current item at specified row with edit data
-    static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm=false);
+    static void draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm=false);
 
-    static void draw(const bool sel, const uint8_t row, FSTR_P const fstr, FSTR_P const inStr) {
-      draw(sel, row, fstr, FTOP(inStr), true);
+    static void draw(const bool sel, const uint8_t row, FSTR_P const ftpl, FSTR_P const fstr) {
+      draw(sel, row, ftpl, FTOP(fstr), true);
     }
 
     // Implementation-specific:
diff --git a/Marlin/src/lcd/menu/menu_advanced.cpp b/Marlin/src/lcd/menu/menu_advanced.cpp
index a4677952d62..e3c7c171d0f 100644
--- a/Marlin/src/lcd/menu/menu_advanced.cpp
+++ b/Marlin/src/lcd/menu/menu_advanced.cpp
@@ -68,8 +68,10 @@ void menu_backlash();
     LOOP_LOGICAL_AXES(i) driverPercent[i] = stepper_dac.get_current_percent((AxisEnum)i);
     START_MENU();
     BACK_ITEM(MSG_ADVANCED_SETTINGS);
-    #define EDIT_DAC_PERCENT(A) EDIT_ITEM(uint8, MSG_DAC_PERCENT_##A, &driverPercent[_AXIS(A)], 0, 100, []{ stepper_dac.set_current_percents(driverPercent); })
-    LOGICAL_AXIS_CODE(EDIT_DAC_PERCENT(E), EDIT_DAC_PERCENT(A), EDIT_DAC_PERCENT(B), EDIT_DAC_PERCENT(C), EDIT_DAC_PERCENT(I), EDIT_DAC_PERCENT(J), EDIT_DAC_PERCENT(K));
+
+    LOOP_LOGICAL_AXES(a)
+      EDIT_ITEM_N(uint8, a, MSG_DAC_PERCENT_N, &driverPercent[a], 0, 100, []{ stepper_dac.set_current_percents(driverPercent); });
+
     ACTION_ITEM(MSG_DAC_EEPROM_WRITE, stepper_dac.commit_eeprom);
     END_MENU();
   }
@@ -427,11 +429,11 @@ void menu_backlash();
     START_MENU();
     BACK_ITEM(MSG_ADVANCED_SETTINGS);
 
-    #define EDIT_VMAX(N) EDIT_ITEM_FAST(float5, MSG_VMAX_##N, &planner.settings.max_feedrate_mm_s[_AXIS(N)], 1, max_fr_edit_scaled[_AXIS(N)])
-    LINEAR_AXIS_CODE(EDIT_VMAX(A), EDIT_VMAX(B), EDIT_VMAX(C), EDIT_VMAX(I), EDIT_VMAX(J), EDIT_VMAX(K));
+    LOOP_NUM_AXES(a)
+      EDIT_ITEM_FAST_N(float5, a, MSG_VMAX_N, &planner.settings.max_feedrate_mm_s[a], 1, max_fr_edit_scaled[a]);
 
     #if E_STEPPERS
-      EDIT_ITEM_FAST(float5, MSG_VMAX_E, &planner.settings.max_feedrate_mm_s[E_AXIS_N(active_extruder)], 1, max_fr_edit_scaled.e);
+      EDIT_ITEM_FAST_N(float5, E_AXIS, MSG_VMAX_N, &planner.settings.max_feedrate_mm_s[E_AXIS_N(active_extruder)], 1, max_fr_edit_scaled.e);
     #endif
     #if ENABLED(DISTINCT_E_FACTORS)
       LOOP_L_N(n, E_STEPPERS)
@@ -514,11 +516,9 @@ void menu_backlash();
       BACK_ITEM(MSG_ADVANCED_SETTINGS);
 
       #if HAS_JUNCTION_DEVIATION
-        #if ENABLED(LIN_ADVANCE)
-          EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.3f, planner.recalculate_max_e_jerk);
-        #else
-          EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, 0.5f);
-        #endif
+        EDIT_ITEM(float43, MSG_JUNCTION_DEVIATION, &planner.junction_deviation_mm, 0.001f, TERN(LIN_ADVANCE, 0.3f, 0.5f)
+          OPTARG(LIN_ADVANCE, planner.recalculate_max_e_jerk)
+        );
       #endif
 
       constexpr xyze_float_t max_jerk_edit =
@@ -532,20 +532,13 @@ void menu_backlash();
           { LOGICAL_AXIS_LIST(990, 990, 990, 990, 990, 990, 990) }
         #endif
       ;
-      #define EDIT_JERK(N) EDIT_ITEM_FAST(float3, MSG_V##N##_JERK, &planner.max_jerk[_AXIS(N)], 1, max_jerk_edit[_AXIS(N)])
-      #if ENABLED(DELTA)
-        #define EDIT_JERK_C() EDIT_JERK(C)
-      #else
-        #define EDIT_JERK_C() EDIT_ITEM_FAST(float52sign, MSG_VC_JERK, &planner.max_jerk.c, 0.1f, max_jerk_edit.c)
-      #endif
-      LINEAR_AXIS_CODE(
-        EDIT_JERK(A), EDIT_JERK(B), EDIT_JERK_C(),
-        EDIT_JERK(I), EDIT_JERK(J), EDIT_JERK(K)
-      );
 
-      #if HAS_EXTRUDERS
-        EDIT_ITEM_FAST(float52sign, MSG_VE_JERK, &planner.max_jerk.e, 0.1f, max_jerk_edit.e);
-      #endif
+      LOOP_LOGICAL_AXES(a) {
+        if (a == C_AXIS || TERN0(HAS_EXTRUDERS, a == E_AXIS))
+          EDIT_ITEM_FAST_N(float52sign, a, MSG_VN_JERK, &planner.max_jerk[a], 0.1f, max_jerk_edit[a]);
+        else
+          EDIT_ITEM_FAST_N(float3, a, MSG_VN_JERK, &planner.max_jerk[a], 1.0f, max_jerk_edit[a]);
+      }
 
       END_MENU();
     }
@@ -582,11 +575,8 @@ void menu_advanced_steps_per_mm() {
   START_MENU();
   BACK_ITEM(MSG_ADVANCED_SETTINGS);
 
-  #define EDIT_QSTEPS(Q) EDIT_ITEM_FAST(float61, MSG_##Q##_STEPS, &planner.settings.axis_steps_per_mm[_AXIS(Q)], 5, 9999, []{ planner.refresh_positioning(); })
-  LINEAR_AXIS_CODE(
-    EDIT_QSTEPS(A), EDIT_QSTEPS(B), EDIT_QSTEPS(C),
-    EDIT_QSTEPS(I), EDIT_QSTEPS(J), EDIT_QSTEPS(K)
-  );
+  LOOP_NUM_AXES(a)
+    EDIT_ITEM_FAST_N(float61, a, MSG_N_STEPS, &planner.settings.axis_steps_per_mm[a], 5, 9999, []{ planner.refresh_positioning(); });
 
   #if ENABLED(DISTINCT_E_FACTORS)
     LOOP_L_N(n, E_STEPPERS)
@@ -598,7 +588,7 @@ void menu_advanced_steps_per_mm() {
           planner.mm_per_step[E_AXIS_N(e)] = 1.0f / planner.settings.axis_steps_per_mm[E_AXIS_N(e)];
       });
   #elif E_STEPPERS
-    EDIT_ITEM_FAST(float61, MSG_E_STEPS, &planner.settings.axis_steps_per_mm[E_AXIS], 5, 9999, []{ planner.refresh_positioning(); });
+    EDIT_ITEM_FAST_N(float61, E_AXIS, MSG_N_STEPS, &planner.settings.axis_steps_per_mm[E_AXIS], 5, 9999, []{ planner.refresh_positioning(); });
   #endif
 
   END_MENU();
@@ -624,7 +614,7 @@ void menu_advanced_settings() {
     #endif
 
     // M203 / M205 - Feedrate items
-    SUBMENU(MSG_VELOCITY, menu_advanced_velocity);
+    SUBMENU(MSG_MAX_SPEED, menu_advanced_velocity);
 
     // M201 - Acceleration items
     SUBMENU(MSG_ACCELERATION, menu_advanced_acceleration);
diff --git a/Marlin/src/lcd/menu/menu_backlash.cpp b/Marlin/src/lcd/menu/menu_backlash.cpp
index faed8cf7776..6b6cdf2e0be 100644
--- a/Marlin/src/lcd/menu/menu_backlash.cpp
+++ b/Marlin/src/lcd/menu/menu_backlash.cpp
@@ -47,7 +47,7 @@ void menu_backlash() {
 
   #define EDIT_BACKLASH_DISTANCE(N) do { \
     editable.decimal = backlash.get_distance_mm(_AXIS(N)); \
-    EDIT_ITEM_FAST(float43, MSG_BACKLASH_##N, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_distance_mm(_AXIS(N), editable.decimal); }); \
+    EDIT_ITEM_FAST_N(float43, _AXIS(N), MSG_BACKLASH_N, &editable.decimal, 0.0f, 9.9f, []{ backlash.set_distance_mm(_AXIS(N), editable.decimal); }); \
   } while (0);
 
   if (_CAN_CALI(A)) EDIT_BACKLASH_DISTANCE(A);
diff --git a/Marlin/src/lcd/menu/menu_configuration.cpp b/Marlin/src/lcd/menu/menu_configuration.cpp
index cb36f4bc98a..8b6af33fd11 100644
--- a/Marlin/src/lcd/menu/menu_configuration.cpp
+++ b/Marlin/src/lcd/menu/menu_configuration.cpp
@@ -572,7 +572,7 @@ void menu_configuration() {
   // Preheat configurations
   #if HAS_PREHEAT && DISABLED(SLIM_LCD_MENUS)
     LOOP_L_N(m, PREHEAT_COUNT)
-      SUBMENU_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings);
+      SUBMENU_N_f(m, ui.get_preheat_label(m), MSG_PREHEAT_M_SETTINGS, _menu_configuration_preheat_settings);
   #endif
 
   #if ENABLED(SOUND_MENU_ITEM)
diff --git a/Marlin/src/lcd/menu/menu_filament.cpp b/Marlin/src/lcd/menu/menu_filament.cpp
index 5e4e1166969..5902a2f63f3 100644
--- a/Marlin/src/lcd/menu/menu_filament.cpp
+++ b/Marlin/src/lcd/menu/menu_filament.cpp
@@ -95,7 +95,7 @@ void _menu_temp_filament_op(const PauseMode mode, const int8_t extruder) {
   BACK_ITEM(MSG_BACK);
   #if HAS_PREHEAT
     LOOP_L_N(m, PREHEAT_COUNT)
-      ACTION_ITEM_N_S(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset);
+      ACTION_ITEM_N_f(m, ui.get_preheat_label(m), MSG_PREHEAT_M, _change_filament_with_preset);
   #endif
   EDIT_ITEM_FAST_N(int3, extruder, MSG_PREHEAT_CUSTOM, &thermalManager.temp_hotend[extruder].target,
     EXTRUDE_MINTEMP, thermalManager.hotend_max_target(extruder),
@@ -132,18 +132,18 @@ void menu_change_filament() {
 
     // Change filament
     #if E_STEPPERS == 1
-      FSTR_P const msg = GET_TEXT_F(MSG_FILAMENTCHANGE);
+      FSTR_P const fmsg = GET_TEXT_F(MSG_FILAMENTCHANGE);
       if (thermalManager.targetTooColdToExtrude(active_extruder))
-        SUBMENU_F(msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); });
+        SUBMENU_F(fmsg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, 0); });
       else
-        GCODES_ITEM_F(msg, F("M600 B0"));
+        GCODES_ITEM_F(fmsg, F("M600 B0"));
     #else
-      FSTR_P const msg = GET_TEXT_F(MSG_FILAMENTCHANGE_E);
+      FSTR_P const fmsg = GET_TEXT_F(MSG_FILAMENTCHANGE_E);
       LOOP_L_N(s, E_STEPPERS) {
         if (thermalManager.targetTooColdToExtrude(s))
-          SUBMENU_N_F(s, msg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); });
+          SUBMENU_N_F(s, fmsg, []{ _menu_temp_filament_op(PAUSE_MODE_CHANGE_FILAMENT, MenuItemBase::itemIndex); });
         else {
-          ACTION_ITEM_N_F(s, msg, []{
+          ACTION_ITEM_N_F(s, fmsg, []{
             PGM_P const cmdpstr = PSTR("M600 B0 T%i");
             char cmd[strlen_P(cmdpstr) + 3 + 1];
             sprintf_P(cmd, cmdpstr, int(MenuItemBase::itemIndex));
@@ -271,10 +271,10 @@ void menu_pause_option() {
 //
 // ADVANCED_PAUSE_FEATURE message screens
 //
-// Warning: msg must have three null bytes to delimit lines!
+// Warning: fmsg must have three null bytes to delimit lines!
 //
-void _lcd_pause_message(FSTR_P const msg) {
-  PGM_P const msg1 = FTOP(msg);
+void _lcd_pause_message(FSTR_P const fmsg) {
+  PGM_P const msg1 = FTOP(fmsg);
   PGM_P const msg2 = msg1 + strlen_P(msg1) + 1;
   PGM_P const msg3 = msg2 + strlen_P(msg2) + 1;
   const bool has2 = msg2[0], has3 = msg3[0],
diff --git a/Marlin/src/lcd/menu/menu_item.h b/Marlin/src/lcd/menu/menu_item.h
index 80a0872da65..53cf7c321ea 100644
--- a/Marlin/src/lcd/menu/menu_item.h
+++ b/Marlin/src/lcd/menu/menu_item.h
@@ -268,7 +268,7 @@ class MenuItem_bool : public MenuEditItemBase {
   #define _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER)
 #endif
 
-#define _MENU_INNER_P(TYPE, USE_MULTIPLIER, FLABEL, V...) do { \
+#define _MENU_INNER_F(TYPE, USE_MULTIPLIER, FLABEL, V...) do { \
   FSTR_P const flabel = FLABEL;                                \
   if (encoderLine == _thisItemNr && ui.use_click()) {          \
     _MENU_ITEM_MULTIPLIER_CHECK(USE_MULTIPLIER);               \
@@ -280,30 +280,41 @@ class MenuItem_bool : public MenuEditItemBase {
       (encoderLine == _thisItemNr, _lcdLineNr, flabel, ##V);   \
 }while(0)
 
+// Item with optional data
 #define _MENU_ITEM_F(TYPE, V...) do { \
   if (_menuLineNr == _thisItemNr) {   \
     _skipStatic = false;              \
-    _MENU_INNER_P(TYPE, ##V);         \
+    _MENU_INNER_F(TYPE, ##V);         \
   }                                   \
   NEXT_ITEM();                        \
 }while(0)
 
-// Indexed items set a global index value and optional data
+// Item with index value, C-string, and optional data
 #define _MENU_ITEM_N_S_F(TYPE, N, S, V...) do{ \
   if (_menuLineNr == _thisItemNr) {            \
     _skipStatic = false;                       \
     MenuItemBase::init(N, S);                  \
-    _MENU_INNER_P(TYPE, ##V);                  \
+    _MENU_INNER_F(TYPE, ##V);                  \
   }                                            \
   NEXT_ITEM();                                 \
 }while(0)
 
-// Indexed items set a global index value
+// Item with index value and F-string
+#define _MENU_ITEM_N_f_F(TYPE, N, f, V...) do{ \
+  if (_menuLineNr == _thisItemNr) {            \
+    _skipStatic = false;                       \
+    MenuItemBase::init(N, f);                  \
+    _MENU_INNER_F(TYPE, ##V);                  \
+  }                                            \
+  NEXT_ITEM();                                 \
+}while(0)
+
+// Item with index value
 #define _MENU_ITEM_N_F(TYPE, N, V...) do{ \
   if (_menuLineNr == _thisItemNr) {       \
     _skipStatic = false;                  \
-    MenuItemBase::itemIndex = N;          \
-    _MENU_INNER_P(TYPE, ##V);             \
+    MenuItemBase::init(N);                \
+    _MENU_INNER_F(TYPE, ##V);             \
   }                                       \
   NEXT_ITEM();                            \
 }while(0)
@@ -312,8 +323,18 @@ class MenuItem_bool : public MenuEditItemBase {
 #define _MENU_ITEM_S_F(TYPE, S, V...) do{ \
   if (_menuLineNr == _thisItemNr) {       \
     _skipStatic = false;                  \
-    MenuItemBase::itemString = S;         \
-    _MENU_INNER_P(TYPE, ##V);             \
+    MenuItemBase::init(0, S);             \
+    _MENU_INNER_F(TYPE, ##V);             \
+  }                                       \
+  NEXT_ITEM();                            \
+}while(0)
+
+// Items with a unique F-string
+#define _MENU_ITEM_f_F(TYPE, f, V...) do{ \
+  if (_menuLineNr == _thisItemNr) {       \
+    _skipStatic = false;                  \
+    MenuItemBase::init(0, f);             \
+    _MENU_INNER_F(TYPE, ##V);             \
   }                                       \
   NEXT_ITEM();                            \
 }while(0)
@@ -361,15 +382,24 @@ class MenuItem_bool : public MenuEditItemBase {
 #define STATIC_ITEM(LABEL, V...)                       STATIC_ITEM_F(GET_TEXT_F(LABEL), ##V)
 #define STATIC_ITEM_N(LABEL, N, V...)                STATIC_ITEM_N_F(GET_TEXT_F(LABEL), N, ##V)
 
+// Menu item with index and composed C-string substitution
 #define MENU_ITEM_N_S_F(TYPE, N, S, FLABEL, V...)   _MENU_ITEM_N_S_F(TYPE, N, S, false, FLABEL, ##V)
 #define MENU_ITEM_N_S(TYPE, N, S, LABEL, V...)       MENU_ITEM_N_S_F(TYPE, N, S, GET_TEXT_F(LABEL), ##V)
+
+// Menu item with composed C-string substitution
 #define MENU_ITEM_S_F(TYPE, S, FLABEL, V...)          _MENU_ITEM_S_F(TYPE, S, false, FLABEL, ##V)
 #define MENU_ITEM_S(TYPE, S, LABEL, V...)              MENU_ITEM_S_F(TYPE, S, GET_TEXT_F(LABEL), ##V)
+
+// Menu item substitution, indexed
 #define MENU_ITEM_N_F(TYPE, N, FLABEL, V...)          _MENU_ITEM_N_F(TYPE, N, false, FLABEL, ##V)
 #define MENU_ITEM_N(TYPE, N, LABEL, V...)              MENU_ITEM_N_F(TYPE, N, GET_TEXT_F(LABEL), ##V)
+
+// Basic menu items, no substitution
 #define MENU_ITEM_F(TYPE, FLABEL, V...)                 _MENU_ITEM_F(TYPE, false, FLABEL, ##V)
 #define MENU_ITEM(TYPE, LABEL, V...)                     MENU_ITEM_F(TYPE, GET_TEXT_F(LABEL), ##V)
 
+// Predefined menu item types //
+
 #define BACK_ITEM_F(FLABEL)                              MENU_ITEM_F(back, FLABEL)
 #define BACK_ITEM(LABEL)                                   MENU_ITEM(back, LABEL)
 
@@ -418,6 +448,38 @@ class MenuItem_bool : public MenuEditItemBase {
 #define EDIT_ITEM_FAST_F(TYPE, FLABEL, V...)                _MENU_ITEM_F(TYPE, true, FLABEL, ##V)
 #define EDIT_ITEM_FAST(TYPE, LABEL, V...)               EDIT_ITEM_FAST_F(TYPE, GET_TEXT_F(LABEL), ##V)
 
+// F-string substitution instead of C-string //
+
+#define MENU_ITEM_N_f_F(TYPE, N, f, FLABEL, V...)   _MENU_ITEM_N_f_F(TYPE, N, f, false, FLABEL, ##V)
+#define MENU_ITEM_N_f(TYPE, N, f, LABEL, V...)       MENU_ITEM_N_f_F(TYPE, N, f, GET_TEXT_F(LABEL), ##V)
+#define MENU_ITEM_f_F(TYPE, f, FLABEL, V...)          _MENU_ITEM_f_F(TYPE, f, false, FLABEL, ##V)
+#define MENU_ITEM_f(TYPE, f, LABEL, V...)              MENU_ITEM_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V)
+
+#define ACTION_ITEM_N_f_F(N, f, FLABEL, ACTION)      MENU_ITEM_N_f_F(function, N, f, FLABEL, ACTION)
+#define ACTION_ITEM_N_f(N, f, LABEL, ACTION)       ACTION_ITEM_N_f_F(N, f, GET_TEXT_F(LABEL), ACTION)
+#define ACTION_ITEM_f_F(f, FLABEL, ACTION)             MENU_ITEM_f_F(function, f, FLABEL, ACTION)
+#define ACTION_ITEM_f(f, LABEL, ACTION)              ACTION_ITEM_f_F(f, GET_TEXT_F(LABEL), ACTION)
+
+#define GCODES_ITEM_N_f_F(N, f, FLABEL, GCODES)      MENU_ITEM_N_f_F(gcode, N, f, FLABEL, GCODES)
+#define GCODES_ITEM_N_f(N, f, LABEL, GCODES)       GCODES_ITEM_N_f_F(N, f, GET_TEXT_F(LABEL), GCODES)
+#define GCODES_ITEM_f_F(f, FLABEL, GCODES)             MENU_ITEM_f_F(gcode, f, FLABEL, GCODES)
+#define GCODES_ITEM_f(f, LABEL, GCODES)              GCODES_ITEM_f_F(f, GET_TEXT_F(LABEL), GCODES)
+
+#define SUBMENU_N_f_F(N, f, FLABEL, DEST)            MENU_ITEM_N_f_F(submenu, N, f, FLABEL, DEST)
+#define SUBMENU_N_f(N, f, LABEL, DEST)                 SUBMENU_N_f_F(N, f, GET_TEXT_F(LABEL), DEST)
+#define SUBMENU_f_F(f, FLABEL, DEST)                   MENU_ITEM_f_F(submenu, f, FLABEL, DEST)
+#define SUBMENU_f(f, LABEL, DEST)                        SUBMENU_f_F(f, GET_TEXT_F(LABEL), DEST)
+
+#define EDIT_ITEM_N_f_F(TYPE, N, f, FLABEL, V...)    MENU_ITEM_N_f_F(TYPE, N, f, FLABEL, ##V)
+#define EDIT_ITEM_N_f(TYPE, N, f, LABEL, V...)       EDIT_ITEM_N_f_F(TYPE, N, f, GET_TEXT_F(LABEL), ##V)
+#define EDIT_ITEM_f_F(TYPE, f, FLABEL, V...)           MENU_ITEM_f_F(TYPE, f, FLABEL, ##V)
+#define EDIT_ITEM_f(TYPE, f, LABEL, V...)              EDIT_ITEM_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V)
+
+#define EDIT_ITEM_FAST_N_f_F(TYPE, N, f, FLABEL, V...)  _MENU_ITEM_N_f_F(TYPE, N, f, true, FLABEL, ##V)
+#define EDIT_ITEM_FAST_N_f(TYPE, N, f, LABEL, V...) EDIT_ITEM_FAST_N_f_F(TYPE, N, f, true, GET_TEXT_F(LABEL), ##V)
+#define EDIT_ITEM_FAST_f_F(TYPE, f, FLABEL, V...)         _MENU_ITEM_f_F(TYPE, f, true, FLABEL, ##V)
+#define EDIT_ITEM_FAST_f(TYPE, f, LABEL, V...)        EDIT_ITEM_FAST_f_F(TYPE, f, GET_TEXT_F(LABEL), ##V)
+
 #define _CONFIRM_ITEM_INNER_F(FLABEL, V...) do {             \
   if (encoderLine == _thisItemNr && ui.use_click()) {        \
     ui.push_current_screen();                                \
diff --git a/Marlin/src/lcd/menu/menu_motion.cpp b/Marlin/src/lcd/menu/menu_motion.cpp
index 2cfdb078efc..e5d027f2153 100644
--- a/Marlin/src/lcd/menu/menu_motion.cpp
+++ b/Marlin/src/lcd/menu/menu_motion.cpp
@@ -57,6 +57,8 @@
 // "Motion" > "Move Axis" submenu
 //
 
+// TODO: Use substitution here with MSG_MOVE_N
+
 static void _lcd_move_xyz(FSTR_P const name, const AxisEnum axis) {
   if (ui.use_click()) return ui.goto_previous_screen_no_defer();
   if (ui.encoderPosition && !ui.manual_move.processing) {
@@ -187,22 +189,8 @@ void _menu_move_distance(const AxisEnum axis, const screenFunc_t func, const int
     SUBMENU(MSG_MOVE_10MM, []{ _goto_manual_move(10);    });
     SUBMENU(MSG_MOVE_1MM,  []{ _goto_manual_move( 1);    });
     SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move( 0.1f); });
-    if (axis == Z_AXIS && (FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f) {
-      // Determine digits needed right of decimal
-      constexpr uint8_t digs = !UNEAR_ZERO((FINE_MANUAL_MOVE) * 1000 - int((FINE_MANUAL_MOVE) * 1000)) ? 4 :
-                               !UNEAR_ZERO((FINE_MANUAL_MOVE) *  100 - int((FINE_MANUAL_MOVE) *  100)) ? 3 : 2;
-      PGM_P const label = GET_TEXT(MSG_MOVE_N_MM);
-      char tmp[strlen_P(label) + 10 + 1], numstr[10];
-      sprintf_P(tmp, label, dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr));
-      #if DISABLED(HAS_GRAPHICAL_TFT)
-        SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); });
-        MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780));
-        lcd_put_u8str(tmp);
-        MENU_ITEM_ADDON_END();
-      #else
-        SUBMENU_F(FPSTR(tmp), []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); });
-      #endif
-    }
+    if (axis == Z_AXIS && (FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f)
+      SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move(float(FINE_MANUAL_MOVE)); });
   }
   END_MENU();
 }
diff --git a/Marlin/src/lcd/menu/menu_probe_offset.cpp b/Marlin/src/lcd/menu/menu_probe_offset.cpp
index 6271b314f40..c7cbebaade8 100644
--- a/Marlin/src/lcd/menu/menu_probe_offset.cpp
+++ b/Marlin/src/lcd/menu/menu_probe_offset.cpp
@@ -68,21 +68,8 @@ void probe_offset_wizard_menu() {
   SUBMENU(MSG_MOVE_1MM,  []{ _goto_manual_move_z( 1);    });
   SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move_z( 0.1f); });
 
-  if ((FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f) {
-    char tmp[20], numstr[10];
-    // Determine digits needed right of decimal
-    const uint8_t digs = !UNEAR_ZERO((FINE_MANUAL_MOVE) * 1000 - int((FINE_MANUAL_MOVE) * 1000)) ? 4 :
-                         !UNEAR_ZERO((FINE_MANUAL_MOVE) *  100 - int((FINE_MANUAL_MOVE) *  100)) ? 3 : 2;
-    sprintf_P(tmp, GET_TEXT(MSG_MOVE_N_MM), dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr));
-    #if DISABLED(HAS_GRAPHICAL_TFT)
-      SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
-      MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780));
-      lcd_put_u8str(tmp);
-      MENU_ITEM_ADDON_END();
-    #else
-      SUBMENU_F(tmp, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
-    #endif
-  }
+  if ((FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f)
+    SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
 
   ACTION_ITEM(MSG_BUTTON_DONE, []{
     set_offset_and_go_back(calculated_z_offset);
diff --git a/Marlin/src/lcd/menu/menu_temperature.cpp b/Marlin/src/lcd/menu/menu_temperature.cpp
index fb539f006c1..e493972a971 100644
--- a/Marlin/src/lcd/menu/menu_temperature.cpp
+++ b/Marlin/src/lcd/menu/menu_temperature.cpp
@@ -88,14 +88,14 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i
 
     // Indexed "Preheat ABC" and "Heat Bed" items
     #define PREHEAT_ITEMS(M,E) do{ \
-      ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_both(M, MenuItemBase::itemIndex); }); \
-      ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_END_E, []{ _preheat_end(M, MenuItemBase::itemIndex); }); \
+      ACTION_ITEM_N_f(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_both(M, MenuItemBase::itemIndex); }); \
+      ACTION_ITEM_N_f(E, ui.get_preheat_label(M), MSG_PREHEAT_M_END_E, []{ _preheat_end(M, MenuItemBase::itemIndex); }); \
     }while(0)
 
   #elif HAS_MULTI_HOTEND
 
     // No heated bed, so just indexed "Preheat ABC" items
-    #define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_S(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); })
+    #define PREHEAT_ITEMS(M,E) ACTION_ITEM_N_f(E, ui.get_preheat_label(M), MSG_PREHEAT_M_H, []{ _preheat_end(M, MenuItemBase::itemIndex); })
 
   #endif
 
@@ -112,16 +112,16 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i
       #if HOTENDS == 1
 
         #if HAS_HEATED_BED
-          ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, []{ _preheat_both(editable.int8, 0); });
-          ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_END, do_preheat_end_m);
+          ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, []{ _preheat_both(editable.int8, 0); });
+          ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M_END, do_preheat_end_m);
         #else
-          ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
+          ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
         #endif
 
       #elif HAS_MULTI_HOTEND
 
         HOTEND_LOOP() PREHEAT_ITEMS(editable.int8, e);
-        ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_ALL, []() {
+        ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M_ALL, []() {
           const celsius_t t = ui.material_preset[editable.int8].hotend_temp;
           HOTEND_LOOP() thermalManager.setTargetHotend(t, e);
           TERN(HAS_HEATED_BED, _preheat_bed(editable.int8), ui.return_to_status());
@@ -130,7 +130,7 @@ void Temperature::lcd_preheat(const uint8_t e, const int8_t indh, const int8_t i
       #endif
 
       #if HAS_HEATED_BED
-        ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); });
+        ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M_BEDONLY, []{ _preheat_bed(editable.int8); });
       #endif
 
       END_MENU();
@@ -269,9 +269,9 @@ void menu_temperature() {
     LOOP_L_N(m, PREHEAT_COUNT) {
       editable.int8 = m;
       #if HAS_MULTI_HOTEND || HAS_HEATED_BED
-        SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m);
+        SUBMENU_f(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m);
       #elif HAS_HOTEND
-        ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
+        ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
       #endif
     }
   #endif
@@ -296,9 +296,9 @@ void menu_temperature() {
     LOOP_L_N(m, PREHEAT_COUNT) {
       editable.int8 = m;
       #if HAS_MULTI_HOTEND || HAS_HEATED_BED
-        SUBMENU_S(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m);
+        SUBMENU_f(ui.get_preheat_label(m), MSG_PREHEAT_M, menu_preheat_m);
       #else
-        ACTION_ITEM_S(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
+        ACTION_ITEM_f(ui.get_preheat_label(m), MSG_PREHEAT_M, do_preheat_end_m);
       #endif
     }
 
diff --git a/Marlin/src/lcd/menu/menu_tune.cpp b/Marlin/src/lcd/menu/menu_tune.cpp
index 5d4c3a4bfb4..b13c55f80a3 100644
--- a/Marlin/src/lcd/menu/menu_tune.cpp
+++ b/Marlin/src/lcd/menu/menu_tune.cpp
@@ -50,6 +50,8 @@
     #include "../dogm/marlinui_DOGM.h"
   #endif
 
+  // TODO: Replace fmsg with MSG_BABYSTEP_N and index substitution
+
   void _lcd_babystep(const AxisEnum axis, FSTR_P const fmsg) {
     if (ui.use_click()) return ui.goto_previous_screen_no_defer();
     if (ui.encoderPosition) {
@@ -223,13 +225,13 @@ void menu_tune() {
   //
   #if ENABLED(BABYSTEPPING)
     #if ENABLED(BABYSTEP_XY)
-      SUBMENU(MSG_BABYSTEP_X, []{ _lcd_babystep_go(_lcd_babystep_x); });
-      SUBMENU(MSG_BABYSTEP_Y, []{ _lcd_babystep_go(_lcd_babystep_y); });
+      SUBMENU_N(X_AXIS, MSG_BABYSTEP_N, []{ _lcd_babystep_go(_lcd_babystep_x); });
+      SUBMENU_N(Y_AXIS, MSG_BABYSTEP_N, []{ _lcd_babystep_go(_lcd_babystep_y); });
     #endif
     #if ENABLED(BABYSTEP_ZPROBE_OFFSET)
       SUBMENU(MSG_ZPROBE_ZOFFSET, lcd_babystep_zoffset);
     #else
-      SUBMENU(MSG_BABYSTEP_Z, lcd_babystep_z);
+      SUBMENU_N(Z_AXIS, MSG_BABYSTEP_N, lcd_babystep_z);
     #endif
   #endif
 
diff --git a/Marlin/src/lcd/menu/menu_ubl.cpp b/Marlin/src/lcd/menu/menu_ubl.cpp
index 297325348d2..62c1770bd4c 100644
--- a/Marlin/src/lcd/menu/menu_ubl.cpp
+++ b/Marlin/src/lcd/menu/menu_ubl.cpp
@@ -211,10 +211,10 @@ void _lcd_ubl_edit_mesh() {
     #if HAS_PREHEAT
       #if HAS_HEATED_BED
         #define VALIDATE_MESH_GCODE_ITEM(M) \
-          GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPI" STRINGIFY(M)));
+          GCODES_ITEM_N_f(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPI" STRINGIFY(M)));
       #else
         #define VALIDATE_MESH_GCODE_ITEM(M) \
-          GCODES_ITEM_N_S(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPB0I" STRINGIFY(M)));
+          GCODES_ITEM_N_f(M, ui.get_preheat_label(M), MSG_UBL_VALIDATE_MESH_M, F("G28\nG26CPB0I" STRINGIFY(M)));
       #endif
       REPEAT(PREHEAT_COUNT, VALIDATE_MESH_GCODE_ITEM)
     #endif
@@ -317,7 +317,7 @@ void _lcd_ubl_build_mesh() {
     #else
       #define PREHEAT_BED_GCODE(M) ""
     #endif
-    #define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_S(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \
+    #define BUILD_MESH_GCODE_ITEM(M) GCODES_ITEM_f(ui.get_preheat_label(M), MSG_UBL_BUILD_MESH_M, \
       F( \
         "G28\n" \
         PREHEAT_BED_GCODE(M) \
diff --git a/Marlin/src/lcd/menu/menu_x_twist.cpp b/Marlin/src/lcd/menu/menu_x_twist.cpp
index eba22cca620..e46745e8b76 100644
--- a/Marlin/src/lcd/menu/menu_x_twist.cpp
+++ b/Marlin/src/lcd/menu/menu_x_twist.cpp
@@ -100,19 +100,10 @@ void xatc_wizard_menu() {
   SUBMENU(MSG_MOVE_01MM, []{ _goto_manual_move_z( 0.1f); });
 
   if ((FINE_MANUAL_MOVE) > 0.0f && (FINE_MANUAL_MOVE) < 0.1f) {
-    char tmp[20], numstr[10];
     // Determine digits needed right of decimal
     const uint8_t digs = !UNEAR_ZERO((FINE_MANUAL_MOVE) * 1000 - int((FINE_MANUAL_MOVE) * 1000)) ? 4 :
                          !UNEAR_ZERO((FINE_MANUAL_MOVE) *  100 - int((FINE_MANUAL_MOVE) *  100)) ? 3 : 2;
-    sprintf_P(tmp, GET_TEXT(MSG_MOVE_N_MM), dtostrf(FINE_MANUAL_MOVE, 1, digs, numstr));
-    #if DISABLED(HAS_GRAPHICAL_TFT)
-      SUBMENU_F(FPSTR(NUL_STR), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
-      MENU_ITEM_ADDON_START(0 + ENABLED(HAS_MARLINUI_HD44780));
-      lcd_put_u8str(tmp);
-      MENU_ITEM_ADDON_END();
-    #else
-      SUBMENU_F(FPSTR(tmp), []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
-    #endif
+    SUBMENU_f(F(STRINGIFY(FINE_MANUAL_MOVE)), MSG_MOVE_N_MM, []{ _goto_manual_move_z(float(FINE_MANUAL_MOVE)); });
   }
 
   ACTION_ITEM(MSG_BUTTON_DONE, xatc_wizard_set_offset_and_go_to_next_point);
diff --git a/Marlin/src/lcd/tft/tft.h b/Marlin/src/lcd/tft/tft.h
index 435e7c30bf5..67cec2ee1c7 100644
--- a/Marlin/src/lcd/tft/tft.h
+++ b/Marlin/src/lcd/tft/tft.h
@@ -94,7 +94,7 @@ class TFT {
     static void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height) { queue.canvas(x, y, width, height); }
     static void set_background(uint16_t color) { queue.set_background(color); }
     static void add_text(uint16_t x, uint16_t y, uint16_t color, TFT_String tft_string, uint16_t maxWidth = 0) { queue.add_text(x, y, color, tft_string.string(), maxWidth); }
-    static void add_text(uint16_t x, uint16_t y, uint16_t color, const char *string, uint16_t maxWidth = 0) { queue.add_text(x, y, color, (uint8_t *)string, maxWidth); }
+    static void add_text(uint16_t x, uint16_t y, uint16_t color, const char *string, uint16_t maxWidth = 0) { queue.add_text(x, y, color, string, maxWidth); }
     static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors) { queue.add_image(x, y, image, colors); }
     static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main = COLOR_WHITE, uint16_t color_background = COLOR_BACKGROUND, uint16_t color_shadow = COLOR_BLACK) { queue.add_image(x, y, image, color_main,  color_background, color_shadow); }
     static void add_bar(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { queue.add_bar(x, y, width, height, color); }
diff --git a/Marlin/src/lcd/tft/tft_queue.cpp b/Marlin/src/lcd/tft/tft_queue.cpp
index 3f604005f9e..25ab452cef3 100644
--- a/Marlin/src/lcd/tft/tft_queue.cpp
+++ b/Marlin/src/lcd/tft/tft_queue.cpp
@@ -215,13 +215,13 @@ void TFT_Queue::handle_queue_overflow(uint16_t sizeNeeded) {
   }
 }
 
-void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth) {
+void TFT_Queue::add_text(uint16_t x, uint16_t y, uint16_t color, const uint8_t *string, uint16_t maxWidth) {
   handle_queue_overflow(sizeof(parametersCanvasText_t) + maxWidth);
   parametersCanvas_t *task_parameters = (parametersCanvas_t *)(((uint8_t *)last_task) + sizeof(queueTask_t));
   parametersCanvasText_t *parameters = (parametersCanvasText_t *)end_of_queue;
   last_parameter = end_of_queue;
 
-  uint8_t *pointer = string;
+  const uint8_t *pointer = string;
 
   parameters->type = CANVAS_ADD_TEXT;
   parameters->x = x;
diff --git a/Marlin/src/lcd/tft/tft_queue.h b/Marlin/src/lcd/tft/tft_queue.h
index 51387254c55..55d0a526b5e 100644
--- a/Marlin/src/lcd/tft/tft_queue.h
+++ b/Marlin/src/lcd/tft/tft_queue.h
@@ -139,7 +139,10 @@ class TFT_Queue {
     static void fill(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color);
     static void canvas(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
     static void set_background(uint16_t color);
-    static void add_text(uint16_t x, uint16_t y, uint16_t color, uint8_t *string, uint16_t maxWidth);
+    static void add_text(uint16_t x, uint16_t y, uint16_t color, const uint8_t *string, uint16_t maxWidth);
+    static void add_text(uint16_t x, uint16_t y, uint16_t color, const char *string, uint16_t maxWidth) {
+      add_text(x, y, color, (uint8_t *)string, maxWidth);
+    }
 
     static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t *colors);
     static void add_image(int16_t x, int16_t y, MarlinImage image, uint16_t color_main, uint16_t color_background, uint16_t color_shadow);
diff --git a/Marlin/src/lcd/tft/tft_string.cpp b/Marlin/src/lcd/tft/tft_string.cpp
index 7dca9c589d6..8585d1d82ff 100644
--- a/Marlin/src/lcd/tft/tft_string.cpp
+++ b/Marlin/src/lcd/tft/tft_string.cpp
@@ -35,7 +35,7 @@
 glyph_t *TFT_String::glyphs[256];
 font_t *TFT_String::font_header;
 
-uint8_t TFT_String::data[];
+char TFT_String::data[];
 uint16_t TFT_String::span;
 uint8_t TFT_String::length;
 
@@ -84,24 +84,22 @@ void TFT_String::set() {
   length = 0;
 }
 
-uint8_t read_byte(uint8_t *byte) { return *byte; }
-
 /**
  * Add a string, applying substitutions for the following characters:
  *
- *   $ displays an inserted C-string given by the inStr parameter
+ *   $ displays the string given by fstr or cstr
  *   = displays  '0'....'10' for indexes 0 - 10
  *   ~ displays  '1'....'11' for indexes 0 - 10
  *   * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
  *   @ displays an axis name such as XYZUVW, or E for an extruder
  */
-void TFT_String::add(uint8_t *string, int8_t index, uint8_t *inStr/*=nullptr*/) {
+void TFT_String::add(const char *tpl, const int8_t index, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/) {
   wchar_t wchar;
 
-  while (*string) {
-    string = get_utf8_value_cb(string, read_byte, &wchar);
+  while (*tpl) {
+    tpl = get_utf8_value_cb(tpl, read_byte_ram, &wchar);
     if (wchar > 255) wchar |= 0x0080;
-    uint8_t ch = uint8_t(wchar & 0x00FF);
+    const uint8_t ch = uint8_t(wchar & 0x00FF);
 
     if (ch == '=' || ch == '~' || ch == '*') {
       if (index >= 0) {
@@ -111,10 +109,12 @@ void TFT_String::add(uint8_t *string, int8_t index, uint8_t *inStr/*=nullptr*/)
         add_character('0' + inum);
       }
       else
-        add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED));
+        add(index == -2 ? GET_TEXT_F(MSG_CHAMBER) : GET_TEXT_F(MSG_BED));
     }
-    else if (ch == '$' && inStr)
-      add(inStr);
+    else if (ch == '$' && fstr)
+      add(fstr);
+    else if (ch == '$' && cstr)
+      add(cstr);
     else if (ch == '@')
       add_character(axis_codes[index]);
     else
@@ -123,19 +123,19 @@ void TFT_String::add(uint8_t *string, int8_t index, uint8_t *inStr/*=nullptr*/)
   eol();
 }
 
-void TFT_String::add(uint8_t *string, uint8_t max_len) {
+void TFT_String::add(const char *cstr, uint8_t max_len/*=MAX_STRING_LENGTH*/) {
   wchar_t wchar;
-  while (*string && max_len) {
-    string = get_utf8_value_cb(string, read_byte, &wchar);
+  while (*cstr && max_len) {
+    cstr = get_utf8_value_cb(cstr, read_byte_ram, &wchar);
     if (wchar > 255) wchar |= 0x0080;
-    uint8_t ch = uint8_t(wchar & 0x00FF);
+    const uint8_t ch = uint8_t(wchar & 0x00FF);
     add_character(ch);
     max_len--;
   }
   eol();
 }
 
-void TFT_String::add_character(uint8_t character) {
+void TFT_String::add_character(const char character) {
   if (length < MAX_STRING_LENGTH) {
     data[length] = character;
     length++;
@@ -143,7 +143,7 @@ void TFT_String::add_character(uint8_t character) {
   }
 }
 
-void TFT_String::rtrim(uint8_t character) {
+void TFT_String::rtrim(const char character) {
   while (length) {
     if (data[length - 1] == 0x20 || data[length - 1] == character) {
       length--;
@@ -155,7 +155,7 @@ void TFT_String::rtrim(uint8_t character) {
   }
 }
 
-void TFT_String::ltrim(uint8_t character) {
+void TFT_String::ltrim(const char character) {
   uint16_t i, j;
   for (i = 0; (i < length) && (data[i] == 0x20 || data[i] == character); i++) {
     span -= glyph(data[i])->DWidth;
@@ -166,7 +166,7 @@ void TFT_String::ltrim(uint8_t character) {
   eol();
 }
 
-void TFT_String::trim(uint8_t character) {
+void TFT_String::trim(const char character) {
   rtrim(character);
   ltrim(character);
 }
diff --git a/Marlin/src/lcd/tft/tft_string.h b/Marlin/src/lcd/tft/tft_string.h
index 7fd87bdf527..5940a48ac98 100644
--- a/Marlin/src/lcd/tft/tft_string.h
+++ b/Marlin/src/lcd/tft/tft_string.h
@@ -21,6 +21,8 @@
  */
 #pragma once
 
+// TODO: Make AVR-compatible with separate ROM / RAM string methods
+
 #include <stdint.h>
 
 extern const uint8_t ISO10646_1_5x7[];
@@ -67,14 +69,15 @@ class TFT_String {
     static glyph_t *glyphs[256];
     static font_t *font_header;
 
-    static uint8_t data[MAX_STRING_LENGTH + 1];
+    static char data[MAX_STRING_LENGTH + 1];
     static uint16_t span;   // in pixels
-    static uint8_t length;  // in characters
 
-    static void add_character(uint8_t character);
-    static void eol() { data[length] = 0x00; }
+    static void add_character(const char character);
+    static void eol() { data[length] = '\0'; }
 
   public:
+    static uint8_t length;  // in characters
+
     static void set_font(const uint8_t *font);
     static void add_glyphs(const uint8_t *font);
 
@@ -83,31 +86,69 @@ class TFT_String {
     static glyph_t *glyph(uint8_t character) { return glyphs[character] ?: glyphs[0x3F]; }  /* Use '?' for unknown glyphs */
     static glyph_t *glyph(uint8_t *character) { return glyph(*character); }
 
+    /**
+     * @brief Set the string empty
+     */
     static void set();
-    static void add(uint8_t character) { add_character(character); eol(); }
-    static void add(uint8_t *string, uint8_t max_len=MAX_STRING_LENGTH);
-    static void add(uint8_t *string, int8_t index, uint8_t *inStr=nullptr);
-    static void set(uint8_t *string) { set(); add(string); };
-    static void set(uint8_t *string, int8_t index, const char *inStr=nullptr) { set(); add(string, index, (uint8_t *)inStr); };
-    static void set(const char *string) { set((uint8_t *)string); }
-    static void set(const char *string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)string, index, inStr); }
-    static void add(const char *string) { add((uint8_t *)string); }
 
-    static void add(FSTR_P const string, uint8_t max_len=MAX_STRING_LENGTH) { add((uint8_t *)FTOP(string), max_len); }
-    static void add(FSTR_P const string, int8_t index, uint8_t *inStr=nullptr) { add((uint8_t *)FTOP(string), index, inStr); }
-    static void set(FSTR_P const string) { set((uint8_t *)FTOP(string)); }
-    static void set(FSTR_P const string, int8_t index, const char *inStr=nullptr) { set((uint8_t *)FTOP(string), index, inStr); }
-    static void add(FSTR_P const string) { add((uint8_t *)FTOP(string)); }
+    /**
+     * @brief Append an ASCII character and EOL
+     *
+     * @param character The ASCII character
+     */
+    static void add(const char character) { add_character(character); eol(); }
+    static void set(wchar_t character) { set(); add(character); }
 
-    static void trim(uint8_t character=0x20);
-    static void rtrim(uint8_t character=0x20);
-    static void ltrim(uint8_t character=0x20);
+    /**
+     * @brief Append / Set C-string
+     *
+     * @param cstr The string
+     * @param max_len Character limit
+     */
+    static void add(const char *cstr, uint8_t max_len=MAX_STRING_LENGTH);
+    static void set(const char *cstr, uint8_t max_len=MAX_STRING_LENGTH) { set(); add(cstr, max_len); }
 
-    static void truncate(uint8_t maxlen) { if (length > maxlen) { length = maxlen; eol(); } }
+    /**
+     * @brief Append / Set F-string
+     *
+     * @param fstr The string
+     * @param max_len Character limit
+     */
+    static void add(FSTR_P const fstr, uint8_t max_len=MAX_STRING_LENGTH) { add(FTOP(fstr), max_len); }
+    static void set(FSTR_P const fstr, uint8_t max_len=MAX_STRING_LENGTH) { set(FTOP(fstr), max_len); }
 
+    /**
+     * @brief Append / Set C-string with optional substitution
+     *
+     * @param tpl A string with optional substitution
+     * @param index An index
+     * @param cstr An SRAM C-string to use for $ substitution
+     * @param fstr A ROM F-string to use for $ substitution
+     */
+    static void add(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr);
+    static void set(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(tpl, index, cstr, fstr); }
+
+    /**
+     * @brief Append / Set F-string with optional substitution
+     *
+     * @param ftpl A ROM F-string with optional substitution
+     * @param index An index
+     * @param cstr An SRAM C-string to use for $ substitution
+     * @param fstr A ROM F-string to use for $ substitution
+     */
+    static void add(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { add(FTOP(ftpl), index, cstr, fstr); }
+    static void set(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(ftpl, index, cstr, fstr); }
+
+    // Common string ops
+    static void trim(const char character=' ');
+    static void rtrim(const char character=' ');
+    static void ltrim(const char character=' ');
+    static void truncate(const uint8_t maxlen) { if (length > maxlen) { length = maxlen; eol(); } }
+
+    // Accessors
+    static char *string() { return data; }
     static uint16_t width() { return span; }
-    static uint8_t *string() { return data; }
-    static uint16_t center(uint16_t width) { return span > width ? 0 : (width - span) / 2; }
+    static uint16_t center(const uint16_t width) { return span > width ? 0 : (width - span) / 2; }
 };
 
 extern TFT_String tft_string;
diff --git a/Marlin/src/lcd/tft/ui_1024x600.cpp b/Marlin/src/lcd/tft/ui_1024x600.cpp
index e8ba4737a80..a1b6ee69e3b 100644
--- a/Marlin/src/lcd/tft/ui_1024x600.cpp
+++ b/Marlin/src/lcd/tft/ui_1024x600.cpp
@@ -181,13 +181,13 @@ void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater) {
 
   tft.add_image(8, 28, image, Color);
 
-  tft_string.set((uint8_t *)i16tostr3rj(currentTemperature));
+  tft_string.set(i16tostr3rj(currentTemperature));
   tft_string.add(LCD_STR_DEGREE);
   tft_string.trim();
   tft.add_text(tft_string.center(80) + 2, 82, Color, tft_string);
 
   if (targetTemperature >= 0) {
-    tft_string.set((uint8_t *)i16tostr3rj(targetTemperature));
+    tft_string.set(i16tostr3rj(targetTemperature));
     tft_string.add(LCD_STR_DEGREE);
     tft_string.trim();
     tft.add_text(tft_string.center(80) + 2, 8, Color, tft_string);
@@ -211,7 +211,7 @@ void draw_fan_status(uint16_t x, uint16_t y, const bool blink) {
 
   tft.add_image(8, 20, image, COLOR_FAN);
 
-  tft_string.set((uint8_t *)ui8tostr4pctrj(thermalManager.fan_speed[0]));
+  tft_string.set(ui8tostr4pctrj(thermalManager.fan_speed[0]));
   tft_string.trim();
   tft.add_text(tft_string.center(80) + 6, 82, COLOR_FAN, tft_string);
 }
@@ -359,7 +359,7 @@ void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const va
   uint16_t line = 1;
 
   menu_line(line++);
-  tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString));
+  tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
   tft_string.trim();
   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
 
@@ -606,7 +606,7 @@ static void quick_feedback() {
 
 #define CUR_STEP_VALUE_WIDTH 104
 static void drawCurStepValue() {
-  tft_string.set((uint8_t *)ftostr52sp(motionAxisState.currentStepSize));
+  tft_string.set(ftostr52sp(motionAxisState.currentStepSize));
   tft_string.add("mm");
   tft.canvas(motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT);
   tft.set_background(COLOR_BACKGROUND);
diff --git a/Marlin/src/lcd/tft/ui_320x240.cpp b/Marlin/src/lcd/tft/ui_320x240.cpp
index 148d5d3964c..15031d0da2e 100644
--- a/Marlin/src/lcd/tft/ui_320x240.cpp
+++ b/Marlin/src/lcd/tft/ui_320x240.cpp
@@ -181,13 +181,13 @@ void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater) {
 
   tft.add_image(0, 18, image, Color);
 
-  tft_string.set((uint8_t *)i16tostr3rj(currentTemperature));
+  tft_string.set(i16tostr3rj(currentTemperature));
   tft_string.add(LCD_STR_DEGREE);
   tft_string.trim();
   tft.add_text(tft_string.center(64) + 2, 72, Color, tft_string);
 
   if (targetTemperature >= 0) {
-    tft_string.set((uint8_t *)i16tostr3rj(targetTemperature));
+    tft_string.set(i16tostr3rj(targetTemperature));
     tft_string.add(LCD_STR_DEGREE);
     tft_string.trim();
     tft.add_text(tft_string.center(64) + 2, 8, Color, tft_string);
@@ -211,7 +211,7 @@ void draw_fan_status(uint16_t x, uint16_t y, const bool blink) {
 
   tft.add_image(0, 10, image, COLOR_FAN);
 
-  tft_string.set((uint8_t *)ui8tostr4pctrj(thermalManager.fan_speed[0]));
+  tft_string.set(ui8tostr4pctrj(thermalManager.fan_speed[0]));
   tft_string.trim();
   tft.add_text(tft_string.center(64) + 6, 72, COLOR_FAN, tft_string);
 }
@@ -354,7 +354,7 @@ void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const va
   uint16_t line = 1;
 
   menu_line(line++);
-  tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString));
+  tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
   tft_string.trim();
   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
 
@@ -588,7 +588,7 @@ static void quick_feedback() {
 
 #define CUR_STEP_VALUE_WIDTH 38
 static void drawCurStepValue() {
-  tft_string.set((uint8_t *)ftostr52sp(motionAxisState.currentStepSize));
+  tft_string.set(ftostr52sp(motionAxisState.currentStepSize));
   tft.canvas(motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, 20);
   tft.set_background(COLOR_BACKGROUND);
   tft.add_text(CUR_STEP_VALUE_WIDTH - tft_string.width(), 0, COLOR_AXIS_HOMED, tft_string);
diff --git a/Marlin/src/lcd/tft/ui_480x320.cpp b/Marlin/src/lcd/tft/ui_480x320.cpp
index 34502df5402..5a964525ecd 100644
--- a/Marlin/src/lcd/tft/ui_480x320.cpp
+++ b/Marlin/src/lcd/tft/ui_480x320.cpp
@@ -181,13 +181,13 @@ void draw_heater_status(uint16_t x, uint16_t y, const int8_t Heater) {
 
   tft.add_image(8, 28, image, Color);
 
-  tft_string.set((uint8_t *)i16tostr3rj(currentTemperature));
+  tft_string.set(i16tostr3rj(currentTemperature));
   tft_string.add(LCD_STR_DEGREE);
   tft_string.trim();
   tft.add_text(tft_string.center(80) + 2, 82, Color, tft_string);
 
   if (targetTemperature >= 0) {
-    tft_string.set((uint8_t *)i16tostr3rj(targetTemperature));
+    tft_string.set(i16tostr3rj(targetTemperature));
     tft_string.add(LCD_STR_DEGREE);
     tft_string.trim();
     tft.add_text(tft_string.center(80) + 2, 8, Color, tft_string);
@@ -211,7 +211,7 @@ void draw_fan_status(uint16_t x, uint16_t y, const bool blink) {
 
   tft.add_image(8, 20, image, COLOR_FAN);
 
-  tft_string.set((uint8_t *)ui8tostr4pctrj(thermalManager.fan_speed[0]));
+  tft_string.set(ui8tostr4pctrj(thermalManager.fan_speed[0]));
   tft_string.trim();
   tft.add_text(tft_string.center(80) + 6, 82, COLOR_FAN, tft_string);
 }
@@ -359,7 +359,7 @@ void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const va
   uint16_t line = 1;
 
   menu_line(line++);
-  tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString));
+  tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
   tft_string.trim();
   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
 
@@ -593,7 +593,7 @@ static void quick_feedback() {
 
 #define CUR_STEP_VALUE_WIDTH 104
 static void drawCurStepValue() {
-  tft_string.set((uint8_t *)ftostr52sp(motionAxisState.currentStepSize));
+  tft_string.set(ftostr52sp(motionAxisState.currentStepSize));
   tft_string.add("mm");
   tft.canvas(motionAxisState.stepValuePos.x, motionAxisState.stepValuePos.y, CUR_STEP_VALUE_WIDTH, BTN_HEIGHT);
   tft.set_background(COLOR_BACKGROUND);
diff --git a/Marlin/src/lcd/tft/ui_common.cpp b/Marlin/src/lcd/tft/ui_common.cpp
index 023ff59ca6d..c9e069dbbd6 100644
--- a/Marlin/src/lcd/tft/ui_common.cpp
+++ b/Marlin/src/lcd/tft/ui_common.cpp
@@ -96,16 +96,15 @@ void lcd_moveto(const lcd_uint_t col, const lcd_uint_t row) {
   lcd_gotopixel(int(col) * (TFT_COL_WIDTH), int(row) * MENU_LINE_HEIGHT);
 }
 
-int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
+int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
   if (max_length < 1) return 0;
-  tft_string.set();
-  tft_string.add(c);
+  tft_string.set(c);
   tft.add_text(MENU_TEXT_X_OFFSET, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
   lcd_gotopixel((cursor.x + 1) * (TFT_COL_WIDTH) + tft_string.width(), cursor.y * MENU_LINE_HEIGHT);
   return tft_string.width();
 }
 
-int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
+int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
   if (max_length < 1) return 0;
   tft_string.set(utf8_pstr);
   tft_string.trim();
@@ -115,7 +114,7 @@ int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
   return tft_string.width();
 }
 
-int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
+int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
   return lcd_put_u8str_max_P(utf8_str, max_length);
 }
 
@@ -133,7 +132,7 @@ void lcd_put_int(const int i) {
 void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) {
   menu_item(row, sel);
 
-  uint8_t *string = (uint8_t *)FTOP(fstr);
+  const char *string = FTOP(fstr);
   MarlinImage image = noImage;
   switch (*string) {
     case 0x01: image = imgRefresh; break;  // LCD_STR_REFRESH
@@ -147,18 +146,19 @@ void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, c
     tft.add_image(MENU_ITEM_ICON_X, MENU_ITEM_ICON_Y, image, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND);
   }
 
-  tft_string.set(string, itemIndex, FTOP(itemString));
+  tft_string.set(string, itemIndex, itemStringC, itemStringF);
+
   tft.add_text(offset, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
 }
 
 // Draw a menu item with a (potentially) editable value
-void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const data, const bool pgm) {
+void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
   menu_item(row, sel);
 
-  tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString));
+  tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
   tft.add_text(MENU_TEXT_X_OFFSET, MENU_TEXT_Y_OFFSET, COLOR_MENU_TEXT, tft_string);
-  if (data) {
-    tft_string.set(data);
+  if (inStr) {
+    tft_string.set(inStr);
     tft.add_text(TFT_WIDTH - MENU_TEXT_X_OFFSET - tft_string.width(), MENU_TEXT_Y_OFFSET, COLOR_MENU_VALUE, tft_string);
   }
 }
@@ -166,7 +166,7 @@ void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr
 // Draw a static item with no left-right margin required. Centered by default.
 void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
   menu_item(row);
-  tft_string.set(FTOP(fstr), itemIndex, FTOP(itemString));
+  tft_string.set(fstr, itemIndex, itemStringC, itemStringF);
   if (vstr) tft_string.add(vstr);
   tft.add_text(tft_string.center(TFT_WIDTH), MENU_TEXT_Y_OFFSET, COLOR_YELLOW, tft_string);
 }
diff --git a/Marlin/src/libs/L64XX/L64XX_Marlin.cpp b/Marlin/src/libs/L64XX/L64XX_Marlin.cpp
index a8c2695630d..df3f26f66ae 100644
--- a/Marlin/src/libs/L64XX/L64XX_Marlin.cpp
+++ b/Marlin/src/libs/L64XX/L64XX_Marlin.cpp
@@ -38,7 +38,7 @@ L64XX_Marlin L64xxManager;
 #include "../../HAL/shared/Delay.h"
 
 static const char LINEAR_AXIS_LIST(
-                   str_X[] PROGMEM = "X ",          str_Y[] PROGMEM = "Y ",          str_Z[] PROGMEM = "Z ",
+                   str_X[] PROGMEM = "X ",      str_Y[] PROGMEM = "Y ",      str_Z[] PROGMEM = "Z ",
                    str_I[] PROGMEM = STR_I " ", str_J[] PROGMEM = STR_J " ", str_K[] PROGMEM = STR_K " "
                  ),
                  str_X2[] PROGMEM = "X2", str_Y2[] PROGMEM = "Y2",
diff --git a/buildroot/share/fonts/genpages.c b/buildroot/share/fonts/genpages.c
index dea5b05c5c8..8009e553fa6 100644
--- a/buildroot/share/fonts/genpages.c
+++ b/buildroot/share/fonts/genpages.c
@@ -66,7 +66,7 @@ wchar_t get_val_utf82uni(uint8_t *pstart) {
  */
 uint8_t* get_utf8_value(uint8_t *pstart, wchar_t *pval) {
   uint32_t val = 0;
-  uint8_t *p = pstart;
+  const uint8_t *p = pstart;
   /*size_t maxlen = strlen(pstart);*/
 
   assert(NULL != pstart);