Repository navigation
Workspace polish round 1: New session, verdict colour, anchored popovers, send-order filmstrip, phone swipe - #8
Merged
Conversation
Resume ↵ stays the primary verb; a fresh start is the quieter secondary verb (⌥↵) instead of disappearing. Every column state gets a tested verb set, and the workspace harness fiber carries a resumable session. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
One recipe in the board's pigments: Temper in verdigris, Discard in the deletion red (--kbn-discarded), tinted fill, ink and border mixed against the paper and ink in force, with hover and focus states. The Desk card, the act zone, the review plate and the undo toast all wear it; an e2e checks hue and AA contrast on default and Night Chart paper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
anchoredPopover places a panel against the control that opened it, flips or shifts it to stay inside the viewport and above the phone's bottom bar, follows it through scrolling, and promotes it to the top layer so no ancestor overflow clips it and no transformed stage moves it. The Meeting menu, the in-flight verdict menu, the parent search, the document menu and the channel switcher all use it. The agent and effort selects open an anchored list on a fine pointer (the select stays the value and its change event the commit; a finger keeps the platform picker). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
…elivery A channel reads its fiber page first, then documents declared in the body and never sent (body order), then sent documents by first delivery, oldest first, then sends of unknown time. A re-send keeps its place and gains the fresh mark. Unit and e2e tests that assumed recency order assert send order instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
One touch recognizer serves the reader and sandboxed reports: a one-finger swipe that starts 24 px inside either edge, turns decisively sideways within 10 px and keeps clear of content that pans sideways (scrollable regions, sliders, media, editing, a live selection, pinch zoom). The track follows the finger with the neighbour flat beside it, resists past the ends, and settles on a velocity-scaled release curve. Reports recognise the swipe in-frame and send bounded travel through the document bridge; the reader decides. Wide markdown tables scroll inside themselves on the phone so the page keeps its width and its swipe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…keyboard Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rs, keyboard-aware page bar Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The fiber page's act zone carries the worker pill, drawn with the same plate and wording as the sidebar card, and nothing else draws worker state in the reader. Awaiting-review Temper and Discard ride the navbar as a compact pair beside the fiber's name on every delivered page; on the phone they sit beside the page sheet's heading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
… the phone The folded settings line keeps each fact whole and lets the host:path yield to an ellipsis, so it never runs under History. The page-count row clips the separator that leads any wrapped line. Docs name the fiber page's worker pill and the navbar verdict pair; the landscape phone keeps a one-row top bar (the pair lives in the page sheet). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
The layout lands at once; the sidebar slides in or out on translate and opacity while the stage and tab strip glide back from where they were, on the standard curve. Cards no longer fly from the Desk on a toggle (they still do on arrival), the covered left neighbour fades with the column instead of blinking, and reduced motion lands instantly. An e2e checks the slide's duration, its properties, a constant page width and one-way motion. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
…orker pill The pair is built once per reviewing fiber state rather than on every paint, so a repaint never swaps buttons under the pointer, and both it and the act zone's worker pill disappear when hidden instead of leaving an empty row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
c clicks the worker pill's own destination on the Desk and in the reader, with . as its alias; the sidebar moves to s (⌘\\ unchanged). conversation stays out of the document-forwarded allowlist, so a report cannot open it, and the hostile-key tests post c to prove it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
…hored popovers and pickers, send-order filmstrip, worker plate retired, 220 ms sidebar slide, c opens conversation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> # Conflicts: # ui/src/board/workspace/Reader.ts
Under full-suite load the phone reader's open outlasted the 2.5 s state poll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
A latched page swipe parked the track at its follow offset whenever its release never reached the reader: a live report replaced or suspended mid-swipe, a selection or channel change, a release arriving without a measurable stage, or a report that moves once and never ends. The reader now cancels in place on selection, show and hide, on an unmeasurable release, and after 500 ms without movement; DocumentHost turns the departure of the frame that started a swipe into a cancel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
A reveal.js deck (touch-action pinch-zoom or pan-y) or a carousel that handles its own touches also paged the reader. The page-swipe recognizer now treats content as claimed when its touch-action withholds either pan from the browser, and decides the latch in a bubble-phase window listener, after the content's handlers, dropping a touch the content has already prevented. The reader's bottom bar opts back in with data-ws-swipe="on". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
The parent-search dropdown was placed once, on its first render; when it opened above a field low in the viewport, taller later results grew down over the field. anchorPopover's release now carries reposition(), and the dropdown calls it on every render of its results. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
dx used screenX but dy used clientY, so a frame shifting under the finger (the phone top bar hiding or showing) read as vertical travel and a sideways swipe was rejected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the first polish round on the document workspace, from Cail's first day of use. It also adds swiping between pages on the phone.
Opus 5.5 on behalf of Cail.
What changes
New session is back. When a session can be resumed, Resume ↵ is the primary verb and a quieter New session (⌥↵) sits beside it. Before, the fresh-start verb was hidden whenever a session was resumable. New session still asks before cutting a live worker.
Verdicts carry colour. Temper is verdigris and Discard is the Desk's deletion red (
--kbn-discarded). The colours are the same everywhere a verdict appears: the Desk card, the fiber page's act zone, the navbar pair and the undo toast. They are mixed against the paper in force, so they stay legible under every theme.Popovers stay with their trigger. A new
anchoredPopover.tsplaces each panel in the browser's top layer, flips and shifts it inside the viewport (and above the phone's bottom bar), and follows the trigger. It is used by the Meeting menu, the document menu, the channel switcher, the parent search and the in-flight ⋯ menu. The agent and effort pickers open an anchored list on desktop; a finger keeps the platform picker.The filmstrip runs in send order: the constitution first, then documents declared in the body and never sent, in body order, then sent documents by first delivery, oldest first. A re-send keeps its place and gets the fresh mark.
The floating worker plate is gone. Worker state lives in one place, the fiber page's act-zone pill, the same component the sidebar card uses. While a fiber awaits review, a compact Temper/Discard pair sits beside the fiber name in the navbar, or in the page sheet on the phone.
The sidebar toggle is one 220 ms slide, animating only
translateandopacity. It is instant under reduced motion.Keys:
c(and.) opens the conversation;s(and ⌘\) toggles the Constitutions sidebar.Phone swipe. A horizontal swipe on the page itself steps pages: the page follows the finger, resists at the ends, and settles from the release speed. The swipe yields to:
touch-actionor prevent the touch.Sandboxed reports recognise the swipe inside the frame and send bounded travel through the bridge. The parent accepts it only from the selected, active frame. A swipe whose release is lost is cancelled.
Phone layout:
Sidebar slide, frame by frame:
The screenshots come from the fixture harness. Live-data shots and the iOS Simulator recordings are in the felt constitution
ai-futures/felt/constitutions/document-workspace(shots-7/).Review
An independent Opus review found no trust-boundary escape:
swipebridge message can move a hostile report at most one page;conversationstays out of the keys a report can forward;It confirmed three bugs, all fixed with tests that failed before the fix:
A fourth fix measures both swipe axes in screen space inside frames. Without it, a sideways swipe read as vertical whenever the phone top bar moved the frame.
Verification
Observed on this head:
npm test: 1,534 tests passed under each pinned time zone, on Node 25 and on Node 22 (CI's runtime).npm run typecheck: clean.npm run e2e: 91/91.make build SKIP_CLI=1: passes.The phone swipe was exercised in iOS 26.5 Simulator Safari, on the harness and on live data. Native PDF pages keep their own touches, so the bottom bar steps past them. Whether Safari's real edge-back gesture still works was not verified in the Simulator.
🤖 Generated with Claude Code
https://claude.ai/code/session_01LwX9WpuD7VnV6mfmN9eb67