LearnNewsExamplesServices
Frontmatter
id14970
titleDock reveal overlay remains painted after dismiss because hidden state loses the CSS cascade
stateClosed
labels
bugai
assigneesneo-gpt
createdAtJul 10, 2026, 4:44 PM
updatedAtJul 10, 2026, 9:11 PM
githubUrlhttps://github.com/neomjs/neo/issues/14970
authorneo-fable-clio
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 10, 2026, 9:11 PM
milestonev13.2

Dock reveal overlay remains painted after dismiss because hidden state loses the CSS cascade

neo-fable-clio
neo-fable-clio commented on Jul 10, 2026, 4:44 PM

Context

Found by the PR #14966 pixel gate while visually verifying the reveal choreography on examples/dashboard/dock. The original stale-delta hypothesis was intentionally provisional and is now falsified by exact-head instrumentation.

Verified Problem

The worker, VDOM, and real DOM all apply the hidden class correctly, but the overlay remains physically painted after dismissal:

  • five live reveal/dismiss cycles produced 10/10 expected DOM class mutations;
  • worker config, VDOM class state, and DOM class state agreed throughout;
  • with the regression locator bound to the stable overlay node, the pre-fix journey fails because neo-dashboard-dock-reveal-overlay-hidden is present while computed display remains flex.

The previous selector excluded the node as soon as the hidden class appeared, so toBeHidden() could pass against an empty locator while the actual overlay remained visible.

Root Cause

  1. .neo-dashboard-dock-reveal-overlay-hidden and the later generic .neo-flex-container rule have equal specificity. The later display:flex wins, so semantic hidden state does not produce physical hidden state.
  2. Once the cascade is corrected, a second masked defect appears: focusReveal() runs before the main thread paints the hidden-to-visible update, so a genuinely hidden overlay cannot accept focus.

This is a main-thread style/focus-order defect, not a worker-delta defect.

Fix

  • Raise only the semantic hidden selector to .neo-dashboard-dock-reveal-overlay.neo-dashboard-dock-reveal-overlay-hidden, making the visibility contract independent of stylesheet order.
  • Await the component update before moving real browser focus into a reveal, guarded by current visibility and destruction state.
  • Keep the whitebox locator bound to the stable DOM node and directly count token-scoped animationstart events across re-reveal.

Acceptance Criteria

  • Root cause identified with live worker/VDOM/DOM class evidence; the original missing-delta premise is falsified.
  • Hidden state physically removes the overlay on Escape, outside-click, and hover-grace dismissal across five repeated whitebox journeys.
  • Regression coverage runs at the owning browser-rendered tier and cannot pass by losing its locator.
  • The token-scoped reveal animation starts on initial reveal and restarts on re-reveal in every repeated journey.
  • Real focus still enters the overlay after it becomes paint-visible.

Evidence

  • Focused unit contract: 7/7 passed.
  • Focused Neural Link whitebox journey: 5/5 repeated runs passed on Chromium, including physical hidden state, focus, and animation restart.
  • Theme build and compiled-selector inspection confirm the higher-specificity hidden rule.
  • node --check and git diff --check pass.

Out of Scope

  • Token-scope mounting itself, delivered by PR #14971.
  • Changes to choreography classes or DockMotionSignal; both remain correct at their owning tier.

Decision Record impact

none — defect fix; no ADR authority changed.

Related: #14966 Related: #14969 Related: #14971

Origin Session ID: 019f484c-662f-7f31-969a-cbde373efd4a Retrieval Hint: "dock reveal hidden class flex cascade focus before paint animation restart"

tobiu referenced in commit 5406f6c - "fix(dashboard): restore dock reveal visibility and focus (#14970) (#14975)" on Jul 10, 2026, 9:11 PM
tobiu closed this issue on Jul 10, 2026, 9:11 PM