Problem
Multiple visible UI regressions on the Control UI shell from the v2026.3.13-1 sync (04a7853f0f). Two confirmed symptoms with the same root cause:
Symptom 1 — Sidebar nav group headers render as raw text +/− (instead of styled chevrons), with no group spacing/colors/borders. The Chat, Control, Agent, Settings group headers display the literal +/− characters from app-render.ts:270 as fallback content because the corresponding CSS classes are undefined.
Symptom 2 — Topbar overlap: page title (Overview) overlaps the brand block (REMOTECLAW / Gateway Dashboard) because the flex containers that previously positioned them are unstyled.
Root cause
Sync 04a7853f0f (v2026.3.13-1, 751 commits) brought in upstream's ui/src/styles/layout.css wholesale, which had renamed several class families as part of upstream's dashboard-v2 refactor. The fork's ui/src/ui/app-render.ts was NOT touched by the same sync (it's heavily fork-diverged: 2 rebrand commits + 6 gut commits + 1 prior-sync-regression remediation), so it still references the OLD class names.
The result: render code emits classes that no CSS rule defines → unstyled fallback rendering.
Affected class renames (extracted from git show 04a7853f0f -- ui/src/styles/layout.css):
| Render code uses (fork) |
Upstream CSS now has |
.nav-group |
.nav-section |
.nav-group__items |
.nav-section__items |
.nav-group--collapsed |
.nav-section--collapsed |
.nav-label |
.nav-section__label |
.nav-label--static |
(removed entirely) |
.nav-label__text |
.nav-section__label-text |
.nav-label__chevron |
.nav-section__chevron (now expects an SVG child, not text) |
.topbar-left |
(removed; layout reorganized) |
.brand-text |
(removed) |
.brand-sub |
(removed) |
.topbar-status .theme-toggle |
.topbar-status .theme-orb__trigger |
.topbar-status .theme-icon |
.topbar-search family |
app-render.ts lines using these classes:
213 — <header class="topbar"> (still defined)
214 — <div class="topbar-left"> ❌ undefined
227 — <div class="brand"> (still defined)
231 — <div class="brand-text"> ❌ undefined
232-233 — <div class="brand-title">REMOTECLAW</div><div class="brand-sub">Gateway Dashboard</div> (.brand-sub undefined)
256 — <div class="nav-group ..."> ❌ undefined
258 — <button class="nav-label"> ❌ undefined
269 — <span class="nav-label__text"> ❌ undefined
270 — <span class="nav-label__chevron">${isGroupCollapsed ? "+" : "−"}</span> ❌ undefined (renders as raw text)
272 — <div class="nav-group__items"> ❌ undefined
278 — <div class="nav-group nav-group--links"> ❌ undefined
279 — <div class="nav-label nav-label--static"> ❌ undefined
Pattern class
This is the second instance of the regression class documented in HQ #57 (gateway-disconnect post-mortem) and HQ #59 (fork-sync risk model). The variant table has been generalized in the personal-config fork-sync skill from "type-definition-only sync without paired class-implementation update" to "definition-site sync without paired call-site update" — covering CSS-class/template-string drift as well as type/class drift.
Notably: the existing build pipeline (pnpm tsgo, pnpm lint, pnpm test) does NOT catch CSS class drift. TypeScript doesn't validate template-string class names; oxlint/stylelint as currently configured don't cross-reference template strings against CSS files. A CSS class consistency lint is the highest-leverage prevention for this variant (see follow-up issue for the lint rule).
Fix options
| # |
Approach |
Effort |
Trade-off |
| 1 |
Restore old CSS rules in a new fork-owned file ui/src/styles/nav-groups.css (recovered from the 04a7853f0f deletion); add @import to ui/src/styles.css. Same for the deleted .topbar-left/.brand-text/.brand-sub rules. |
~30 min |
Stays on legacy class names; future syncs to layout.css won't conflict with the fork-owned restoration file; but fork visually diverges from upstream design choices |
| 2 |
Migrate render code to upstream class names: update ui/src/ui/app-render.ts to use .nav-section* and the new topbar structure. Replace text +/− chevron with an SVG icon (look at upstream's ${icons.chevronDown} reference at upstream app-render.ts:1317 to find the icon source). Accept upstream's visual restyle (uppercase nav labels, tighter padding, etc.). |
1-2 h |
Aligned with upstream design; future syncs land cleanly; permanently resolves this regression class for these components |
Recommend option 2 — option 1 just delays the same conflict to the next time upstream restyles these components. Option 2 future-proofs by making fork's render code track upstream's class vocabulary.
Acceptance criteria
Commit message
fix(ui): restore nav-section/topbar class names after v2026.3.13-1 sync — paired call-site update missed
or
refactor(ui): migrate app-render.ts to upstream nav-section + topbar class vocabulary — resolve sync drift
References
Problem
Multiple visible UI regressions on the Control UI shell from the v2026.3.13-1 sync (
04a7853f0f). Two confirmed symptoms with the same root cause:Symptom 1 — Sidebar nav group headers render as raw text
+/−(instead of styled chevrons), with no group spacing/colors/borders. TheChat,Control,Agent,Settingsgroup headers display the literal+/−characters fromapp-render.ts:270as fallback content because the corresponding CSS classes are undefined.Symptom 2 — Topbar overlap: page title (
Overview) overlaps the brand block (REMOTECLAW/Gateway Dashboard) because the flex containers that previously positioned them are unstyled.Root cause
Sync
04a7853f0f(v2026.3.13-1, 751 commits) brought in upstream'sui/src/styles/layout.csswholesale, which had renamed several class families as part of upstream's dashboard-v2 refactor. The fork'sui/src/ui/app-render.tswas NOT touched by the same sync (it's heavily fork-diverged: 2 rebrand commits + 6 gut commits + 1 prior-sync-regression remediation), so it still references the OLD class names.The result: render code emits classes that no CSS rule defines → unstyled fallback rendering.
Affected class renames (extracted from
git show 04a7853f0f -- ui/src/styles/layout.css):.nav-group.nav-section.nav-group__items.nav-section__items.nav-group--collapsed.nav-section--collapsed.nav-label.nav-section__label.nav-label--static.nav-label__text.nav-section__label-text.nav-label__chevron.nav-section__chevron(now expects an SVG child, not text).topbar-left.brand-text.brand-sub.topbar-status .theme-toggle.topbar-status .theme-orb__trigger.topbar-status .theme-icon.topbar-searchfamilyapp-render.tslines using these classes:213—<header class="topbar">(still defined)214—<div class="topbar-left">❌ undefined227—<div class="brand">(still defined)231—<div class="brand-text">❌ undefined232-233—<div class="brand-title">REMOTECLAW</div><div class="brand-sub">Gateway Dashboard</div>(.brand-subundefined)256—<div class="nav-group ...">❌ undefined258—<button class="nav-label">❌ undefined269—<span class="nav-label__text">❌ undefined270—<span class="nav-label__chevron">${isGroupCollapsed ? "+" : "−"}</span>❌ undefined (renders as raw text)272—<div class="nav-group__items">❌ undefined278—<div class="nav-group nav-group--links">❌ undefined279—<div class="nav-label nav-label--static">❌ undefinedPattern class
This is the second instance of the regression class documented in HQ #57 (gateway-disconnect post-mortem) and HQ #59 (fork-sync risk model). The variant table has been generalized in the personal-config
fork-syncskill from "type-definition-only sync without paired class-implementation update" to "definition-site sync without paired call-site update" — covering CSS-class/template-string drift as well as type/class drift.Notably: the existing build pipeline (
pnpm tsgo,pnpm lint,pnpm test) does NOT catch CSS class drift. TypeScript doesn't validate template-string class names; oxlint/stylelint as currently configured don't cross-reference template strings against CSS files. A CSS class consistency lint is the highest-leverage prevention for this variant (see follow-up issue for the lint rule).Fix options
ui/src/styles/nav-groups.css(recovered from the04a7853f0fdeletion); add@importtoui/src/styles.css. Same for the deleted.topbar-left/.brand-text/.brand-subrules.layout.csswon't conflict with the fork-owned restoration file; but fork visually diverges from upstream design choicesui/src/ui/app-render.tsto use.nav-section*and the new topbar structure. Replace text+/−chevron with an SVG icon (look at upstream's${icons.chevronDown}reference at upstreamapp-render.ts:1317to find the icon source). Accept upstream's visual restyle (uppercase nav labels, tighter padding, etc.).Recommend option 2 — option 1 just delays the same conflict to the next time upstream restyles these components. Option 2 future-proofs by making fork's render code track upstream's class vocabulary.
Acceptance criteria
+/−characters visible).theme-orb__triggerif migrating)pnpm check(tsgo + lint + format) passespnpm testpasses/overview,/chat,/agentsand verify layout sanity in light + dark themesCommit message
or
References
remoteclaw/hq#57remoteclaw/hq#59remoteclaw/hq#58