# UX Redesign — Implementation Plan Reference mock: `docs/mocks/v09_full_ux.html` Target hardware: 10.8" portable monitor, 1920×1080, capacitive touch, Chrome fullscreen. ## 1. Goals The redesign keeps every existing feature but reorganizes the page into a single-screen control surface for finger-touch use: - A slim 96 px header replaces the 140 px nav-header. Only logo + ONEFINITY wordmark + tab bar + system pill + READY badge + octagonal STOP. - 4 top-level sections accessed via underline-ribbon tabs in the header: 1. **Control** — jog pad, DRO table, status strip, macro row. 2. **Program** — Auto run controls, file actions, G-code listing, 3D viewer. 3. **Console** — MDI, Messages, Indicators (sub-tabs). 4. **Settings** — paged settings (replaces the Pure left rail). - Touch targets ≥ 64 px (jog tiles 72 px, axis action icons 72 px, macro buttons 84 px). - All action chip-soup (WiFi/Camera/Rotary/IP/Version) collapses into one "All systems · view" pill that opens a popover. Burger menu removed (Settings tab supersedes it). - V09 jog/macro palette: flat soft slate (#3f4b63), no drop shadow; yellow (#fde047) accent for active states (step seg, tab underline, macro number badge). - Spindle override / feed override sliders live in a bottom-edge drawer triggered by tapping the Spindle KPI tile (no permanent screen real estate). - Hard cut: no `config.ui.layout` flag; the new shell replaces the old in a single release. ## 2. Scope of code change The build is Pug + Stylus + Browserify Vue (Vue 1.x). `index.pug` defines the chrome; `src/pug/templates/*.pug` defines each view; `src/js/*.js` mirrors them as Vue components routed by `currentView` from the URL hash. Files we will touch: - `src/pug/index.pug` — replace `#layout / #menu / #main / .nav-header` with the new header + tab bar + body. Drop the burger and the side-menu include. - `src/pug/templates/control-view.pug` — restructure into the new Control panel (jog grid + DRO table + status strip + macro row). MDI/Messages/Indicators move out. - New `src/pug/templates/program-view.pug` — Auto sub-panel content (action bar, file bar, gcode-viewer, path-viewer). - New `src/pug/templates/console-view.pug` — MDI / Messages / Indicators sub-tabs hosting existing `console.pug` and `indicators.pug` partials. - `src/js/app.js` — extend `parse_hash` so `#program`, `#console`, `#settings` resolve; expose tab state for the header to highlight. - `src/js/control-view.js` — keep jog/DRO logic, drop the Auto/MDI/Messages/Indicators internal `tab` state and template hooks. - New `src/js/program-view.js`, `src/js/console-view.js` — extracted Vue components. - `src/stylus/style.styl` — add `.app-shell`, `.head`, `.tabs-host`, `.ktab`, panel styles, V09 jog tokens. Keep legacy classes alive until templates fully migrated. - `src/static/css/side-menu.css` — stop including in `index.pug`. - Settings: keep `settings-view.pug`, `admin-general-view.pug`, `admin-network-view.pug`, `motor-view.pug`, `tool-view.pug`, `io-view.pug`, etc., and surface them through a left-rail navigator inside the Settings panel rather than the sidebar. - Settings → Macros owns the full macro list (1…N). Control's macro row is a slice of the first 8; reordering happens in Settings. ## 3. Routing model We keep the existing URL hash routing because everything in `src/js/app.js#parse_hash` and the deep-linked menu items (`#motor:0`, `#admin-network`, etc.) depend on it. | URL hash | Top tab | Notes | |-------------------------|------------|-------------------------------------------------------| | `#control` | Control | Default | | `#program` / `#program:auto` | Program | Auto sub-view (only sub-view for now) | | `#console` / `#console:mdi` | Console | MDI default, also `:messages` and `:indicators` | | `#settings` | Settings | Settings home (Display & Units) | | `#admin-general`, `#admin-network`, `#motor:N`, `#tool`, `#io`, `#help`, `#cheat-sheet` | Settings | Existing routes remain, surfaced in the Settings left rail | The header tab bar maps URL prefix → active tab. A tiny helper `topTabFromHash(hash)` lives in `app.js` and is reused by the header template. ## 4. Step-by-step ### Phase 1 — Mock parity (1–2 days) 1. Add `docs/mocks/v09_full_ux.html` (done) so anyone can preview the target. 2. Move the V09 palette into Stylus tokens at the top of `style.styl`: ```styl $jog-bg = #3f4b63 $jog-hover = #4a5777 $jog-dir = #5b6885 $jog-ghost = #8c97ad $accent = #fde047 $accent-ink = #0f172a ``` 3. Build the header in `index.pug`: ```pug .app-shell header.head .brand-blk .brand-logo .brand-name ONEFINITY nav.tabs-host(role="tablist") a.ktab(:class="{active: topTab === 'control'}", href="#control") .fa.fa-gamepad | Control a.ktab(:class="{active: topTab === 'program'}", href="#program") … a.ktab(:class="{active: topTab === 'console'}", href="#console") … a.ktab(:class="{active: topTab === 'settings'}", href="#settings") … button.sys-btn(@click="toggle_sys_popover") … span.state-badge(:class="state_class") estop(@click="estop") ``` 4. Style the header tabs as **underline ribbon** (V02): transparent fills, slate-gray text, dark text + 5 px yellow underline on active. CSS already proven in the mock. 5. Move the rotary toggle and pi-temp warning into the system pill popover. ### Phase 2 — Control panel (2 days) 1. Rewrite the outer markup of `control-view.pug` to a CSS grid: ``` .control-grid → 720px jog-card | 1fr right-col(dro-card + status-strip) ``` Drop the ``-based outer layout (axes table stays — it's a real data table). 2. Replace the legacy `