Context
Found by the PR #14966 pixel gate (2026-07-10): the first visual verification of the dock motion pipeline after the #14947 tokens → #14944 FLIP → #14966 choreography classes all landed/converged. Every prior verification tier (unit specs, Neural-Link topology assertions, hosted CI) exercises worker truth or committed state — none of it watches rendered pixels, which is exactly where this gap lives.
The Problem
The entire dock motion contract lives in resources/scss/src/dashboard/Container.scss: the --dock-transition-* token set scoped to .neo-dashboard, the reduced-motion collapse, the reveal keyframes, the arrival settle class, splitter cursors, rail/reveal-overlay hooks. The css-map loads that file with Neo.dashboard.Container instances — and neither dock-zone surface ever creates one:
examples/dashboard/dock (the ADR 0029 verification surface) projects plain containers via DockLayoutAdapter; its element tree carries neo-dashboard-dock-* classes but no .neo-dashboard scope element and no src/dashboard/Container.css stylesheet.
apps/agentos/childapps/dockdemo (Demo A): same shape, same absence.
Measured on both surfaces (live, dev server, 2026-07-10):
--dock-transition-duration computes UNSET everywhere; dashboard/Container.css absent from document.styleSheets.
- Splitter cursor computes
pointer (Container.scss says ew-resize/ns-resize) — even though DockSplitter IS instantiated, its styles live in the un-loaded Container.scss file.
- Edge-band width is flex-derived (~92px), not the stylesheet's 280px.
Consequences, post token-only convergence:
Neo.main.addon.DockFlip (6cbc2dff6b) reads tokens as its SOLE motion authority and fails safe to instant → FLIP re-layouts are instant (motion-less) on both dock surfaces. The Demo-A tour lost its glide the moment the (correct) polish merged.
- The
#14966 choreography classes (reveal slide, arrival settle) reference token durations and keyframes that don't exist on these surfaces → no visible motion.
observe_motion / tour-runner step gating key off motion that can never render here.
Injection proof (same session): manually appending dist/development/css/src/dashboard/Container.css + stamping neo-dashboard on the projection root restores everything — tokens compute 260ms / cubic-bezier(0, 0, 0.2, 1), the reveal keyframes run a clean 0.4→1 opacity ramp over 260ms, the arrival outline decays over ~390ms. The CSS tier is fully correct; only the loading/scope is missing. (A DOM-stamped scope also dies on every re-projection — the fix must live in the projection/component tier.)
The FM cockpit is NOT affected: apps/agentos/view/Viewport.mjs mounts a real Neo.dashboard.Container, so the cockpit dashboard loads the file and carries the scope. That is why the token layer looked verified at #14947 review time — its home surface genuinely has it.
The Architectural Reality
- The css-map loads theme CSS per instantiated class:
resources/scss/src/dashboard/Container.scss ↔ Neo.dashboard.Container. Classes the adapter merely names in cls strings load nothing.
Neo.dashboard.Container itself is the detach-to-window dashboard (drag proxy + popup machinery) — making dock hosts extend/instantiate it would drag interaction semantics the dock-zone reducer pattern does not want.
- The landed opt-in mechanism for cross-class theme loading already exists:
additionalThemeFiles (used by DemoAWorkspace for the AgentOS token bridge).
The Fix
Two shapes, recommendation first:
A (minimal, recommended for the July window): each dock workspace declares additionalThemeFiles: ['Neo.dashboard.Container'] and adds neo-dashboard to its host cls (vdom truth, not DOM patching) — examples/dashboard/dock/MainContainer and the dockdemo DemoAWorkspace. Two small diffs, no new classes, uses the landed mechanism.
B (structural, post-window candidate): a thin Neo.dashboard host class (baseCls ['neo-dashboard', ...], no detach machinery) that DockLayoutAdapter emits as the projection root — every consumer gets scope + CSS automatically, and the dock rules migrate out of Container.scss into its own theme file. Bundle-by-default says A now, B as a follow-up decision when a third consumer appears.
Acceptance Criteria
Out of Scope
- The DockRevealOverlay hidden-cls delta defect (separate ticket, filed alongside this one).
- Shape B's host-class migration (follow-up if/when accepted).
- Any change to the token values or motion classes themselves — they are verified correct.
Decision Record impact
aligned-with ADR 0029 — presentation tier; restores the §2.x motion observability the token contract assumes.
Related: #14947 (token contract) · #14944 (FLIP, token-only authority) · #14966 (choreography classes, the gate that found this) · #14959 (drop-indicator menu — its styles ride the same file) · parent #13158.
Live latest-open sweep: latest 20 open checked at 2026-07-10T14:30Z; nearest is #14968 (tab-insert morph replacement — disjoint mechanism, no overlap). A2A herd window checked (30 msgs, all read-states): no competing claim on surface CSS loading.
Origin Session ID: 183ac080-2f24-4837-8f63-69bfc536af0d
Retrieval Hint: "dock surface neo-dashboard token scope Container.css not loaded motion invisible pixel gate"
Context
Found by the PR
#14966pixel gate (2026-07-10): the first visual verification of the dock motion pipeline after the#14947tokens →#14944FLIP →#14966choreography classes all landed/converged. Every prior verification tier (unit specs, Neural-Link topology assertions, hosted CI) exercises worker truth or committed state — none of it watches rendered pixels, which is exactly where this gap lives.The Problem
The entire dock motion contract lives in
resources/scss/src/dashboard/Container.scss: the--dock-transition-*token set scoped to.neo-dashboard, the reduced-motion collapse, the reveal keyframes, the arrival settle class, splitter cursors, rail/reveal-overlay hooks. The css-map loads that file withNeo.dashboard.Containerinstances — and neither dock-zone surface ever creates one:examples/dashboard/dock(the ADR 0029 verification surface) projects plain containers viaDockLayoutAdapter; its element tree carriesneo-dashboard-dock-*classes but no.neo-dashboardscope element and nosrc/dashboard/Container.cssstylesheet.apps/agentos/childapps/dockdemo(Demo A): same shape, same absence.Measured on both surfaces (live, dev server, 2026-07-10):
--dock-transition-durationcomputes UNSET everywhere;dashboard/Container.cssabsent fromdocument.styleSheets.pointer(Container.scss saysew-resize/ns-resize) — even thoughDockSplitterIS instantiated, its styles live in the un-loaded Container.scss file.Consequences, post token-only convergence:
Neo.main.addon.DockFlip(6cbc2dff6b) reads tokens as its SOLE motion authority and fails safe to instant → FLIP re-layouts are instant (motion-less) on both dock surfaces. The Demo-A tour lost its glide the moment the (correct) polish merged.#14966choreography classes (reveal slide, arrival settle) reference token durations and keyframes that don't exist on these surfaces → no visible motion.observe_motion/ tour-runner step gating key off motion that can never render here.Injection proof (same session): manually appending
dist/development/css/src/dashboard/Container.css+ stampingneo-dashboardon the projection root restores everything — tokens compute260ms/cubic-bezier(0, 0, 0.2, 1), the reveal keyframes run a clean 0.4→1 opacity ramp over 260ms, the arrival outline decays over ~390ms. The CSS tier is fully correct; only the loading/scope is missing. (A DOM-stamped scope also dies on every re-projection — the fix must live in the projection/component tier.)The FM cockpit is NOT affected:
apps/agentos/view/Viewport.mjsmounts a realNeo.dashboard.Container, so the cockpit dashboard loads the file and carries the scope. That is why the token layer looked verified at#14947review time — its home surface genuinely has it.The Architectural Reality
resources/scss/src/dashboard/Container.scss↔Neo.dashboard.Container. Classes the adapter merely names in cls strings load nothing.Neo.dashboard.Containeritself is the detach-to-window dashboard (drag proxy + popup machinery) — making dock hosts extend/instantiate it would drag interaction semantics the dock-zone reducer pattern does not want.additionalThemeFiles(used byDemoAWorkspacefor the AgentOS token bridge).The Fix
Two shapes, recommendation first:
A (minimal, recommended for the July window): each dock workspace declares
additionalThemeFiles: ['Neo.dashboard.Container']and addsneo-dashboardto its hostcls(vdom truth, not DOM patching) —examples/dashboard/dock/MainContainerand the dockdemoDemoAWorkspace. Two small diffs, no new classes, uses the landed mechanism.B (structural, post-window candidate): a thin
Neo.dashboardhost class (baseCls['neo-dashboard', ...], no detach machinery) thatDockLayoutAdapteremits as the projection root — every consumer gets scope + CSS automatically, and the dock rules migrate out of Container.scss into its own theme file. Bundle-by-default says A now, B as a follow-up decision when a third consumer appears.Acceptance Criteria
--dock-transition-duration: 260ms(token default) on the projection scope with zero manual injection.src/dashboard/Container.csspresent indocument.styleSheetson both surfaces.play()returns true on a committed op with default tokens).ew-resize/ns-resizeper orientation.0msunder emulation).Out of Scope
Decision Record impact
aligned-with ADR 0029— presentation tier; restores the §2.x motion observability the token contract assumes.Related:
#14947(token contract) ·#14944(FLIP, token-only authority) ·#14966(choreography classes, the gate that found this) ·#14959(drop-indicator menu — its styles ride the same file) · parent#13158.Live latest-open sweep: latest 20 open checked at 2026-07-10T14:30Z; nearest is
#14968(tab-insert morph replacement — disjoint mechanism, no overlap). A2A herd window checked (30 msgs, all read-states): no competing claim on surface CSS loading.Origin Session ID: 183ac080-2f24-4837-8f63-69bfc536af0d Retrieval Hint: "dock surface neo-dashboard token scope Container.css not loaded motion invisible pixel gate"