Skip to content

Commit aab9e3e

Browse files
author
Ravi Singh
committed
fix: mobile layout + board MCU-mismatch boot guard
Mobile (ERR was: sidebar + bottom-tabs both rendered, scrambling layout): - Added the missing .hide-mobile / .show-mobile rules — they were referenced inline by main.tsx but never defined in styles.css, so on phones the desktop sidebar AND mobile bottom-nav both rendered at once, overlapping every card and pushing the page off-screen - Trimmed paddings, reduced page-head gap, and force-collapse all inline auto-fit grids (220/280 px min-cols) to 2-column at ≤760 px and 1-column at ≤480 px — Hardware/Mesh/Motion screens now lay out cleanly on a 360 px viewport Boot guard (ERR was: 2nd C3 not starting AP after reflash): - resolve_board_profile now rejects an NVS board.id whose profile->mcu doesn't match CONFIG_IDF_TARGET (e.g., "esp32-devkit" pinmap loaded on a C3). Wrong pinmap drives USB-JTAG / flash pins as outputs and bricks boot before netmgr starts, looking like "device dead". Falls back to the compile-time default profile in that case.
1 parent 0b63b6e commit aab9e3e

4 files changed

Lines changed: 51 additions & 5 deletions

File tree

firmware/components/webui/ui.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
128 Bytes
Binary file not shown.

firmware/main/main.c

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,22 @@ static const board_profile_t *resolve_board_profile(void) {
4747
if (err == ESP_OK) {
4848
const board_profile_t *p = board_profile_by_id(saved_id);
4949
if (p) {
50-
ESP_LOGI(TAG, "Board profile from NVS: %s (%s)", p->id, p->display);
51-
return p;
50+
/* MCU mismatch guard: if NVS has a profile from a different SoC
51+
* (e.g., previous "esp32-devkit" saved on a C3 from a stale flash),
52+
* the wrong pin map can drive USB-JTAG / flash pins as outputs and
53+
* brick boot before Wi-Fi comes up. Fall back to the compile-time
54+
* default whenever the saved profile's MCU doesn't match the
55+
* IDF_TARGET we were built for. */
56+
if (strcmp(p->mcu, CONFIG_IDF_TARGET) != 0) {
57+
ESP_LOGW(TAG, "NVS board.id='%s' is for MCU '%s' but we're running on '%s' — falling back",
58+
p->id, p->mcu, CONFIG_IDF_TARGET);
59+
} else {
60+
ESP_LOGI(TAG, "Board profile from NVS: %s (%s)", p->id, p->display);
61+
return p;
62+
}
63+
} else {
64+
ESP_LOGW(TAG, "NVS board.id='%s' is unknown; falling back to default", saved_id);
5265
}
53-
ESP_LOGW(TAG, "NVS board.id='%s' is unknown; falling back to default", saved_id);
5466
}
5567
const board_profile_t *def = board_default_profile();
5668
ESP_LOGI(TAG, "Board profile (default): %s (%s)", def->id, def->display);

frontend/src/styles.css

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,15 @@ input, select, textarea { font: inherit; color: inherit; }
8080
.page-head h1 { font-size: 22px; font-weight: 600; margin: 0; letter-spacing: -0.02em; }
8181
.page-head .sub { color: var(--text-2); font-size: 13px; margin-top: 2px; }
8282

83+
/* Responsive helpers used inline by the layout. Without these the desktop
84+
* sidebar and mobile bottom-tab nav both render at once on phones, which
85+
* is how the UI looked "scrambled" in the v6.0 report. */
86+
.hide-mobile { /* visible on desktop, hidden via media query below */ }
87+
.show-mobile { display: none; }
88+
8389
@media (max-width: 760px) {
90+
.hide-mobile { display: none !important; }
91+
.show-mobile { display: flex !important; }
8492
.app { grid-template-columns: 1fr; }
8593
.sidebar {
8694
position: fixed; bottom: 0; left: 0; right: 0; top: auto; height: auto;
@@ -90,8 +98,34 @@ input, select, textarea { font: inherit; color: inherit; }
9098
}
9199
.brand { display: none; }
92100
.navlink { flex-direction: column; gap: 3px; padding: 6px 8px; font-size: 10px; }
93-
.main { padding: 16px 14px 88px; }
101+
.main { padding: 14px 12px 88px; max-width: 100%; }
102+
.page-head { gap: 8px; margin-bottom: 16px; }
94103
.page-head h1 { font-size: 19px; }
104+
.app-header { padding: 10px 12px; }
105+
/* Cards lose their inner indent on phones — saves ~14 px per card * 4 cards. */
106+
.card-body { padding: 12px 12px 14px; }
107+
.card-head { padding: 12px 12px 0; }
108+
/* Tame inline grids that hardcode min 280 px columns — they'd overflow
109+
* on a 360 px viewport once card padding is subtracted. */
110+
.card .card-body > div[style*="grid-template-columns: repeat(auto-fit"] {
111+
grid-template-columns: 1fr !important;
112+
}
113+
/* LED screen's primary 2-col grid (Mode list | Color/Layout column) —
114+
* stacks vertically on phones. */
115+
.led-grid { grid-template-columns: 1fr !important; gap: 12px !important; }
116+
/* Top-level grid wrappers used by Motion advanced + Hardware pin maps. */
117+
div[style*="grid-template-columns: repeat(auto-fit, minmax(280px, 1fr))"],
118+
div[style*="grid-template-columns: repeat(auto-fit, minmax(220px, 1fr))"],
119+
div[style*="grid-template-columns: repeat(auto-fit, minmax(170px, 1fr))"] {
120+
grid-template-columns: 1fr 1fr !important;
121+
}
122+
div[style*="grid-template-columns: repeat(auto-fit, minmax(155px, 1fr))"] {
123+
grid-template-columns: 1fr 1fr !important;
124+
}
125+
}
126+
@media (max-width: 480px) {
127+
/* Single column on the smallest phones. */
128+
div[style*="grid-template-columns: repeat(auto-fit"] { grid-template-columns: 1fr !important; }
95129
}
96130

97131
/* Atoms */

0 commit comments

Comments
 (0)