Skip to content

mac: the workspace moves on §4's springs - #298

Merged
stupart merged 1 commit into
mainfrom
feat/spec-motion
Sep 16, 2026
Merged

stupart merged 1 commit into
mainfrom
feat/spec-motion

Conversation

@stupart

@stupart stupart commented Sep 16, 2026

Copy link
Copy Markdown
Owner

Tyler: "the js version was much better / smoother." This is the "smoother" half — §4, which I had never read.

ConchMotion already held §4's exact values — morph bounce 0.12 / response 0.46, pop 0.34 / 0.36, with resolved(reduceMotion:) built in. The workspace simply never used them, animating with hand-rolled .easeOut(duration: 0.18) instead. The overlay has used the real springs for months (control-bar-source.test.ts pins them); this applies the same convention to the window.

§4 says was now
⌘B collapse → morph .easeOut(0.18) ConchMotion.morph
side by side / deliverable fill → morph did not animate at all ConchMotion.morph
switching sessions → fade in over 0.12 s, no slide instant swap 0.12 s opacity fade
Reduce Motion → drops the bounce, keeps the timing nil — killed the animation outright resolved(reduceMotion:)

That last row is a behaviour fix, not a value: passing nil made Reduce Motion mean "no animation", where §4 means "no bounce".

The fade is declarative, on purpose

mac-phase1-source forbids imperative animation blocks in the transcript — one that restarts on every streamed token never settles the viewport. My first attempt used one and tripped that guard, which was right to fire. The fade now rides .animation(_:value:) with the value flipped on the next runloop turn, so it cannot touch the scroll path at all.

(My own comment then tripped the same guard by containing the forbidden word. Reworded — the guard is a plain substring check and was correct both times.)

Mutation battery

mutation result
⌘B drifts back to a hand-rolled easing that nils out under Reduce Motion 1 fail
the stage stops moving between its pages 1 fail
the switch fade loses its animation modifier 1 fail
the fade is set in the same frame, so nothing animates 1 fail

Gate

bun test 2303/0 exit 0 · tsc --noEmit exit 0 · swift test exit 0 · Mac xcodebuild BUILD SUCCEEDED · iOS xcodebuild BUILD SUCCEEDED — re-run after rebasing onto #297, since both slices edited DashboardView.swift and the same test file.

A still frame cannot verify this one. conch shot captures a moment; springs are the thing between moments. It builds, it is guarded, and the values are yours from the lab — but judging whether it feels right is on the live window.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE

ConchMotion already held §4's values -- morph bounce 0.12 / response 0.46,
pop 0.34 / 0.36 -- and the workspace never used them, animating with
hand-rolled .easeOut(duration: 0.18) instead. The overlay has used the real
springs for months; this applies the same convention to the window.

⌘B collapse takes morph. The stage's pages take morph and now move at all --
before, the deliverable replaced the conversation between one frame and the
next. Switching sessions fades the transcript in over 0.12s with no slide,
because moving a reading surface is the thing Tyler called distracting.

Reduce Motion now DROPS THE BOUNCE and keeps the timing, which is what §4
says; passing nil had disabled the animation outright, a different promise.

The fade is declarative -- .animation(_:value:) with the value flipped on the
next runloop turn -- never an imperative animation block, which this file's
own guard forbids in the transcript: one that restarts on every streamed
token never settles the viewport.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfEX6bfwCGXtThk1JRNmsE
@stupart
stupart merged commit 2835168 into main Sep 16, 2026
2 checks passed
@stupart
stupart deleted the feat/spec-motion branch September 16, 2026 20:40
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