LearnNewsExamplesServices
Frontmatter
id17211
titleCockpit layout ergonomics: the grid/timeline splitter is invisible, the left rail oversizes its tabs, the right rail undersizes its panels
stateClosed
labels
bugdesignai
assigneesneo-opus-grace
createdAtAug 15, 2026, 10:31 PM
updatedAtAug 23, 2026, 6:16 PM
githubUrlhttps://github.com/neomjs/neo/issues/17211
authorneo-fable-clio
commentsCount2
parentIssue13158
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 23, 2026, 6:16 PM
milestonev13.2

Cockpit layout ergonomics: the grid/timeline splitter is invisible, the left rail oversizes its tabs, the right rail undersizes its panels

Closed Backlog/active-chunk-16 bugdesignai
neo-fable-clio
neo-fable-clio commented on Aug 15, 2026, 10:31 PM

Context

Operator UX escalation (screenshots, 2026-08-15, same session as #17209/#17210 — this ticket owns the LAYOUT AFFORDANCE half; #17209 owns skins/shell):

  1. The splitter between the agent-card grid and the activity timeline is invisible. A resizable boundary exists functionally but carries no visual affordance — no handle, no hover state, no cursor hint. Operators cannot discover it.
  2. Proportion imbalance between the two rails. The left navigation rail (Home / Fleet / Accounts / Chat) renders large — possibly too large — while the right side-tab rail (Agent detail / Perspectives / Add agent / Catch up / Memories / Wake routes / Operator) renders as cramped rotated text, and the panels it opens use their width poorly (small content in a large drawer).
  3. Side-panel content density: the drawer content sits small inside its area — the space is claimed but not used.

Acceptance Criteria

  • The grid/timeline splitter is a designed, discoverable affordance: visible divider, hover/active states, resize cursor — consistent with the fleet look (SCSS token/skin layers only, zero CSS-in-JS).
  • Rail proportions rebalanced: left-rail tab sizing reviewed against its information density; right-rail tabs legible without squinting (size, spacing, active state) — one deliberate proportion decision, documented in the PR body.
  • Drawer content uses its width: pane content lays out to the drawer's actual measure (no fixed narrow column floating in dead space) — verified on the panes that already have skins; the skinless panes inherit this via #17209's shell contract.
  • Acceptance surface: the offline topology (first-run view), light and dark themes.

Sequencing

Independent of #17209's shell/skin work at the splitter + rails level; the drawer-density AC lands cleanest AFTER #17209's shell contract exists — slice accordingly.

Out of Scope

Pane skins and the drawer shell contract (#17209) · static-roster alarm calm-down (#17210) · cross-app style alignment (sibling ticket).

Related

#17209 · #17210 · #13015 (FM umbrella) · #16744 (C3).

Live latest-open sweep: latest 8 checked 2026-08-15T20:2xZ (nearest: #17209/#17210 — same escalation, explicitly split by surface); no equivalent. A2A claim sweep: current-hour window clean.

Origin: operator escalation (screenshots on session dd4568bd) · Retrieval Hint: "cockpit layout splitter invisible rail proportions drawer density ergonomics"

Contract Ledger Matrix

Added 2026-08-23 per PR #17614 review (RA-2, @neo-gpt): the change introduces engine tokens that consumers read, which is a consumed surface and owes a ledger.

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
--dock-edge-rail-size resources/scss/src/dashboard/Container.scss (engine, declared on .neo-dashboard) The edge strip's cross-axis extent, and the single source for it. Read by two consumers that must agree: the rail's own width/height, and the reveal overlay's per-edge inset. Engine default 14px — unchanged, so every existing consumer renders byte-identically. A consumer that sets nothing is unaffected. Rationale beside the declaration, naming the six literals it replaces and why the two readers are coupled. Mutation control: the token is moved 20px → 48px in-page and both readers must follow, since one boot cannot distinguish "coupled" from "two literals that agree today".
--dock-rail-tab-background-active
--dock-rail-tab-color-active
resources/scss/src/dashboard/Container.scss (engine, .neo-dashboard) Paint for the tab whose reveal is currently showing. Applied via the button's own pressed class, after :hover so an open tab never reads as less engaged than a hovered one. color-mix(in srgb, currentColor 14%, transparent) / currentColor — a visible floor rather than transparent, because an invisible affordance is not one; currentColor-relative because the engine cannot know a host palette. Rationale beside the declaration, including why resting/hover stay neutral while this state does not. CI-running component spec, both themes: revealed paint differs from a live resting sibling, and clearing restores it exactly. Removing the engine rule turns both arms red.
Neo.dashboard.DockRail#syncRevealedTabState() src/dashboard/DockRail.mjs Projects the reveal machine's current target onto the matching tab and clears its siblings. Runtime-only; touches no document. Unknown/stale item id clears every mark rather than latching the previous tab. Anchor & Echo JSDoc naming the runtime-only contract and the dockItemId match that excludes the bound overlay. Unit arms for mark / retarget / clear / stale-id; a set-only mutant fails the retarget and stale-id arms.
Consumer value (apps/agentos cockpit) resources/scss/src/apps/agentos/fleet/cockpit/Container.scss Sets the strip to 20px and the active state to panel ground + signal ink. Deliberately NOT the bar's .pressed pair, which is byte-identical to this rail's hover and would make "open" and "hovered" the same picture. §04 proportion record, grounded in the measured label box rather than the stale 18px figure. Live measurement: label box 11px, padding 1+1, demand 13px; e2e asserts the value reaches the strip and is not shadowed by the projected default.
tobiu referenced in commit fa2a34c - "fix(dashboard): the edge rail's measure becomes a token the consumer owns (#17211) (#17614) on Aug 23, 2026, 6:16 PM
tobiu closed this issue on Aug 23, 2026, 6:16 PM