Skip to content

Prototype proximity-gated local surface continuity - #12

Closed
Nocehi wants to merge 8 commits into
mainfrom
feat/rail-surface-morph-prototype
Closed

Nocehi wants to merge 8 commits into
mainfrom
feat/rail-surface-morph-prototype

Conversation

@Nocehi

@Nocehi Nocehi commented Aug 16, 2026 •

Copy link
Copy Markdown
Owner

Scope

Replace the rejected long-distance rail→switcher goo experiment with a narrower presentation prototype: only genuinely local source→surface relationships may read as continuous. dsh-rice must not manufacture a tentacle across the interface.

The ordinary geometry gate is one application-rail width: 56px edge-to-edge.

What this now experiments with

1. Stable accessible source→target relations

The core src/surface-morph.js path remains standards-first:

  • [aria-controls][aria-expanded] → visible controlled target;
  • native <details><summary> → opened content;
  • closest-edge geometry rather than center-to-center travel;
  • one pointer-inert bridge only when the measured edge gap is <= 56px;
  • RAF settling + ResizeObserver + mutation/scroll/resize refresh;
  • normal hover/focus/open/release semantics, with reduced-motion presentation suppressed.

This is the preferred path for Todo/collapsed-card style disclosures. If the live host does not expose a durable accessible relationship, rice stays silent rather than guessing a private class/React seam.

2. Newly-visible nearby semantic popups

src/surface-morph-candidates.js adds a second standards-based candidate path for controls whose popup semantics live on the newly-mounted surface rather than on aria-controls:

  • capture a recent compact button, [role=button], or [aria-haspopup] activation;
  • snapshot semantic popup surfaces already visible before activation;
  • for the next 18 animation frames, consider only newly-visible role=menu, role=listbox, role=dialog, or open native popover surfaces;
  • connect only the nearest candidate within the same 56px edge-gap limit;
  • keep the connector pointer-inert and release it when the popup disappears or leaves the locality gate.

This is intended to dogfood nearby composer action menus/pickers and the dsh-better-sidebar tab-bar + menu without adding a private selector map.

3. dsh-better-sidebar right-workbench corner bloom

The sidebar target here is specifically omdsh-dev/DSH-better-sidebar, while all implementation remains in dsh-rice.

The public betterSidebar client service is authoritative: rice injects it, reads getSnapshot().state, and subscribes with subscribeState(). Existing root hooks still mirror public side/bottom/open/size/maximize state.

The new candidate adapter adds a visual experiment for the right workbench only without querying any Better Sidebar CSS-module class:

  • remember a fresh compact activation only inside the top-right 112px corner;
  • require a subsequent public-service panelOpen transition within the freshness window to prove that activation belonged to the right workbench toggle;
  • obtain panel width from public service state;
  • play a 180ms local corner bloom from the toggle-sized source into a small top-right patch of the real right workbench, then fade out;
  • closing runs the same geometry in reverse when a fresh top-right activation precedes panelOpen: true → false;
  • prefers-reduced-motion: reduce suppresses the bloom;
  • the bloom is pointer-events:none, aria-hidden, and never replaces the real workbench DOM.

The bottom workbench deliberately does not get this bloom: its top-right toggle and bottom destination are spatially non-local and would recreate the rejected tentacle topology.

There is no .dsh-better-sidebar selector, CSS-module substring match, vendored implementation, or modification to the Better Sidebar repository.

Todo / Produced / composer / collapsed-card dogfood paths

  • Todo / collapsed card: use the stable accessible-relation path when the live DSH build exposes one; otherwise remain untouched.
  • Composer: a nearby newly-mounted semantic menu/listbox/dialog/popover may get the short <=56px bridge.
  • Produced: current dsh-better-sidebar owns a produced-files interception whose chips open the editor through public betterSidebar.openTab(...). This is intentionally a locality negative/conditional test: if the real destination is far across the conversation viewport, rice should draw nothing rather than force a cross-viewport transition.
  • Better Sidebar tab +: if the DSH Menu surface mounts semantically and within 56px, it should get only the tiny local bridge.

Acceptance / dogfood questions

  • Does the right-workbench toggle read as a short corner bloom on open and reverse on close, never as a tether or emitted object?
  • Does the 180ms bloom disappear into the real panel quickly enough that recognition and interaction remain immediate?
  • Does the Better Sidebar tab + menu get a tiny local connector when its real semantic menu is nearby, and release cleanly on close?
  • Do nearby composer menus/pickers participate only when a new semantic surface actually appears within 56px?
  • Do Todo/collapsed-card relations work only where the host exposes the stable accessible relation?
  • Does Produced correctly remain animation-free when its real editor destination is non-local?
  • Are side/bottom/split, resize, maximize, session switching, keyboard activation, reduced motion, focus, and hit targets behaviorally unchanged?

Implementation boundary

No new runtime package is added. src/surface-morph.js and src/surface-morph-candidates.js remain dependency-free scripts concatenated into the existing browser artifact; the generated client still allows only the existing React and DSH UI-primitives requires.

Focused tests cover the 56px locality gate, semantic popup discovery, observer lifecycle, Better Sidebar public-service gating, top-right locality/freshness, 180ms reversible bloom, reduced motion, pointer-inert presentation, absence of private sidebar selectors, and build purity.

Exact-head CI on dda1f9227f96837bbf492c5fd7c8657346d94b90 is green (check run #199). Physical dogfood remains the visual merge gate.

@Nocehi
Nocehi force-pushed the feat/rail-surface-morph-prototype branch from 021658b to 59c5b89 Compare August 17, 2026 01:35
@Nocehi
Nocehi changed the base branch from feat/rail-icon-micro-motion to main August 17, 2026 01:35
@Nocehi Nocehi changed the title Prototype rail-to-switcher surface morph Prototype proximity-gated local surface continuity Aug 17, 2026
@Nocehi Nocehi closed this Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant