LearnNewsExamplesServices
Frontmatter
id17543
titleTab strip indicators and the FM container ground join the token layer
stateClosed
labels
enhancementdesignaiagent-os
assigneesneo-fable-clio
createdAtAug 22, 2026, 3:28 PM
updatedAtAug 22, 2026, 4:36 PM
githubUrlhttps://github.com/neomjs/neo/issues/17543
authorneo-fable-clio
commentsCount0
parentIssue14805
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtAug 22, 2026, 4:36 PM

Tab strip indicators and the FM container ground join the token layer

Closed Backlog/active-chunk-18 enhancementdesignaiagent-os
neo-fable-clio
neo-fable-clio commented on Aug 22, 2026, 3:28 PM

Context

Operator design inspection of the live cockpit, 2026-08-22 (paired session): "the new tabs look better … maybe challenge the thickness of the tab strip and the color of the active indicator … 'live activity' has a different background color — intentional? … two active indicators touch each other." Measured in the running cockpit (computed styles on a Neural-Link-connected page), not estimated.

The Problem

Three stock-skin values leak into the FM tonal stack:

  1. Active tab indicators are stock white, 3 px, on both rails. South strip (.neo-dock-top): .neo-active-tab-indicator 3 px tall, rgb(255,255,255). Keeper rail (.neo-dock-left): 3 px wide × the pressed button's full height (FLEET = 83.5 px), also white — although Viewport.scss:11 rebinds --tab-indicator-background-color-active: var(--fm-signal) at the viewport root. The rebind never lands: theme-neo-dark/tab/Strip.scss:2 declares the same token on :root .neo-theme-neo-dark, and the theme class rides the viewport element ITSELF (agent-os-viewport neo-viewport neo-theme-neo-dark) — two equal-specificity (0,2,0) declarations on one element, resolved by load order in the theme's favor: the tie Viewport.scss:198 already documents for --tab-button-*. (Corrected 2026-08-22 13:35Z after a stylesheet-level probe; the first draft said "nearest-ancestor".)
  2. The two indicators touch. At the fleet zone's top-left corner the rail indicator (full button height) meets the fleet-tabs indicator (3 px under "FLEET") at x = 51 — an L of two thick white strokes. Two independent tab containers, no designed bracket: an artifact, and in a dark theme a loud one.
  3. The Activity stream's head and rows sit on a different tone than their root. .fm-activity-stream paints --fm-rail (#0e131a); its .fm-stream-head and every .fm-ev-row are neo-containers and paint the stock --container-background-color (src/container/Base.scss:2 → neo-dark --sem-color-bg-neutral-default, rgb 14,15,13). ActivityStream.scss declares no inner background — the stock skin leaks through. The rows are a hairline list (border-bottom: 1px solid var(--fm-line-soft), radius 0), not boxes; the "box" impression IS the leak. The same leak sits under every FM pane's inner containers (Tasks, Memories) — invisible only where the dock ground happens to be the same stock value.

The Architectural Reality

  • resources/scss/src/tab/Strip.scss + src/tab/header/Button.scss:33-41,71-75 — thickness = --tab-strip-height (height on dock-top; width on dock-left via !important; the per-button .neo-tab-button-indicator reads the same token), color = --tab-indicator-background-color-active; resources/scss/theme-neo-dark/tab/Strip.scss:1-5 binds both on :root .neo-theme-neo-dark — which is the viewport element.
  • The viewport root itself paints the stock neutral (rgb(14,15,13)), not --fm-ground (#0b0e13, defined in both theme twins and consumed only by .agent-welcome): the ground under every pane is a foreign tone too.
  • resources/scss/src/apps/agentos/Viewport.scss:8-11 (root-level color rebind, shadowed) and :192-241 (the one tab family; the .neo-dock-top toolbar block).
  • src/container/Base.scss:2 + theme-neo-dark/container/Base.scss:2 — every container paints the stock neutral unless a skin overrides.
  • The rail indicator's top/height are inline engine geometry; CSS cannot shorten it by height, a clip-path inset can.
  • Prior tickets of the same leak class: #15632 (detail-header background), #15649 (tab-body theme leak — FleetCockpit.scss:23's transparent tab body is its fix).

The Fix

  1. Rebind ON the strip at the FM scope, both rails: .agent-os-viewport .neo-tab-strip { --tab-indicator-background-color-active: var(--fm-signal); --tab-strip-height: 2px; }; retire the shadowed root-level rebind at Viewport.scss:11 or keep it with a comment naming the shadow.
  2. Un-touch the corner: .neo-dock-left .neo-active-tab-indicator { clip-path: inset(var(--fm-space-2) 0); } — trims 8 px at both ends independent of the inline geometry.
  3. FM container ground: --container-background-color: transparent for neo-container descendants under the cockpit / FM pane roots (scope decided at implementation by the blast radius the visual suite shows), so a pane paints only what its token sheet declares.
  4. Refresh the visual goldens the change moves (the visual suite runs outside CI: playwright.config.visual.mjs, NEO_E2E_PORT pinned).

Decision Record impact: none — aligned-with the §04 bar (#17263 / PR #17279) and the one-tab-family cut (#17269).

Acceptance Criteria

  • Both rails' active indicators render --fm-signal at 2 px: computed background-color equals the resolved --fm-signal, and --tab-strip-height resolves to 2px on .neo-tab-strip under the viewport root.
  • The keeper-rail indicator and the fleet-tabs indicator no longer touch: the rail indicator's painted extent is inset by --fm-space-2 at both ends.
  • Inside FM panes, neo-container descendants paint no stock neutral: the Activity head and rows read the stream's own --fm-rail; Tasks / Memories sections read their pane's ground.
  • npm run check-theme-surfaces passes; the 2 px indicator is the only new literal length and is recorded in the file header as a §04 exception.
  • Visual goldens for the cockpit surfaces refreshed, before/after named in the PR. [L3-deferred — operator handoff needed] (annotated 2026-08-22, PR #17544 review round 1): the local-harness baselines are rendered-platform artifacts and fail 7/8 on the UNMODIFIED tree on this seat with identical geometry mismatches, so a refresh here would bake one seat's geometry; surviving owner: #14618 (FM cockpit visual-regression baseline harness). Final close path: this ticket closes with PR #17544; the golden refresh + its verification log land through #14618's harness run, recorded there.

Out of Scope

The 30 px tab BUTTON height (--tab-button-height, Viewport.scss:231 — on the operator's "maybe" list, a separate rhythm call) · south-pane root padding consistency (#17268 pane-composition pass) · rail tab paint duplication across apps (#17522) · splitter visuals (#17538).

Related

Epic #14560 (parent) · #17269 (one tab family) · #17265 (§04 rhythm record) · #17268 · #17522 · #17538 · #15632 / #15649 (prior leak class) · PR #17505 (chrome-tier tab family)

Live latest-open sweep: latest 20 open issues checked 2026-08-22T13:25Z — #17522 and #17538 are adjacent (rail tab paint, splitter), not equivalent; A2A window (30 newest, all read-states) carries no strip/ground claim; local exact sweep: six hits, all CLOSED (prior leak class).

Origin Session ID: 14acab5a-4b6c-4987-91c7-f683e39baa55

Retrieval Hint: query_raw_memories("tab strip indicator fm-signal 2px clip-path inset container background transparent activity stream leak")

tobiu referenced in commit 1cd9d3f - "style(agentos): tab strip indicators and the FM container ground join the token layer (#17543) (#17544) on Aug 22, 2026, 4:36 PM
tobiu closed this issue on Aug 22, 2026, 4:36 PM