feat(core): use LED colors for diode in Eckhart
What changed, and why it matters
This commit is a cosmetic UI change for the Trezor hardware wallet's Eckhart design. It makes the device's RGB LED light up with specific colors on the homescreen and during red-screen error states, matching the screen's theme. There is no security-relevant change to how data is protected, how keys are handled, or how the device communicates.
No security action required. Treat as a normal UI/UX feature commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch introduces dedicated LED color constants (LED_RED, LED_GREEN_LIME, LED_GREEN_LIGHT, LED_ORANGE, LED_YELLOW, LED_BLUE, LED_WHITE) and wires them into the Eckhart homescreen and error screen rendering paths. It also maps those LED colors back to existing display colors when simulating the LED in the emulator/render pipeline. The change is purely presentational and gated behind the existing rgb_led feature flag.
Changed components
core/embed/rust/src/ui/layout_eckhart/component/error.rscore/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rscore/embed/rust/src/ui/layout_eckhart/theme/gradient.rsInspect captured patch +24 / −8
diff --git a/core/embed/rust/src/ui/layout_eckhart/component/error.rs b/core/embed/rust/src/ui/layout_eckhart/component/error.rs
index befea358..a7bd6df1 100644
--- a/core/embed/rust/src/ui/layout_eckhart/component/error.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/component/error.rs
@@ -1,3 +1,6 @@
+#[cfg(feature = "rgb_led")]
+use crate::trezorhal::rgb_led;
+
use crate::{
strutil::TString,
ui::{
@@ -11,8 +14,9 @@ use crate::{
use super::super::{
cshape::ScreenBorder,
theme::{
- ACTION_BAR_HEIGHT, HEADER_HEIGHT, PADDING, RED, SIDE_INSETS, TEXT_NORMAL, TEXT_SMALL,
- TEXT_SMALL_GREY, TEXT_SMALL_GREY_EXTRA_LIGHT, TEXT_SMALL_RED, TEXT_VERTICAL_SPACING,
+ ACTION_BAR_HEIGHT, HEADER_HEIGHT, LED_RED, PADDING, RED, SIDE_INSETS, TEXT_NORMAL,
+ TEXT_SMALL, TEXT_SMALL_GREY, TEXT_SMALL_GREY_EXTRA_LIGHT, TEXT_SMALL_RED,
+ TEXT_VERTICAL_SPACING,
},
WAIT_FOR_RESTART_MESSAGE,
};
@@ -83,5 +87,7 @@ impl<'a> Component for ErrorScreen<'a> {
self.footer.render(target);
self.wait_for_restart.render(target);
self.screen_border.render(u8::MAX, target);
+ #[cfg(feature = "rgb_led")]
+ rgb_led::set_color(LED_RED.into());
}
}
diff --git a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs
index bf60bcd5..a4e9bb1b 100644
--- a/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/firmware/homescreen.rs
@@ -82,7 +82,7 @@ impl Homescreen {
(Some(led_color), Some(hint))
}
None if locked && coinjoin_authorized => (
- Some(theme::GREEN_LIME),
+ Some(theme::LED_GREEN_LIME),
Some(Hint::new_instruction_green(
TR::coinjoin__do_not_disconnect,
Some(theme::ICON_INFO),
@@ -127,15 +127,15 @@ impl Homescreen {
fn get_notification_display(level: u8, text: TString<'static>) -> (Color, Hint<'static>) {
match level {
- 0 => (theme::RED, Hint::new_warning_danger(text)),
- 1 => (theme::YELLOW, Hint::new_warning_neutral(text)),
- 2 => (theme::BLUE, Hint::new_instruction(text, None)),
+ 0 => (theme::LED_RED, Hint::new_warning_danger(text)),
+ 1 => (theme::LED_YELLOW, Hint::new_warning_neutral(text)),
+ 2 => (theme::LED_BLUE, Hint::new_instruction(text, None)),
3 => (
- theme::GREEN_LIGHT,
+ theme::LED_GREEN_LIGHT,
Hint::new_instruction_green(text, Some(theme::ICON_INFO)),
),
_ => (
- theme::GREY_LIGHT,
+ theme::LED_WHITE,
Hint::new_instruction(text, Some(theme::ICON_INFO)),
),
}
diff --git a/core/embed/rust/src/ui/layout_eckhart/theme/gradient.rs b/core/embed/rust/src/ui/layout_eckhart/theme/gradient.rs
index ff1763c2..5ea86e64 100644
--- a/core/embed/rust/src/ui/layout_eckhart/theme/gradient.rs
+++ b/core/embed/rust/src/ui/layout_eckhart/theme/gradient.rs
@@ -149,6 +149,16 @@ fn render_led_simulation<'a>(
step_size: u16,
color: Color,
) {
+ let color = match color {
+ theme::LED_WHITE => theme::GREY_LIGHT,
+ theme::LED_GREEN_LIGHT => theme::GREEN_LIGHT,
+ theme::LED_GREEN_LIME => theme::GREEN_LIME,
+ theme::LED_ORANGE => theme::ORANGE,
+ theme::LED_RED => theme::RED,
+ theme::LED_YELLOW => theme::YELLOW,
+ theme::LED_BLUE => theme::BLUE,
+ _ => color,
+ };
// Vertical gradient (color intensity fading from bottom to top)
for (slice, factor) in iter_slices(area, Axis::Vertical, step_size) {
// Gradient 1 (Overall intensity: 35%)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.