Native motion, own rail icons, and a Translate tab that picks its languages - #11
Merged
ctimothe merged 7 commits intoSep 21, 2026
Merged
Conversation
… screen too Over the lock screen a pause removed the pill in a single frame: the locked branch refuses every animation from outside, and the pill was mounted only while something played. It now stays mounted for the whole lock and answers its own change on its own curve, declared beneath the refusal, so the lock itself is still a cut. Unlocked, the compact header left the tree the instant the pill folded and kept its old width, so the narrowing clip swept across a cover that sat still; it now stays laid out whenever the panel is shut and rides the wings in while PillPresence dissolves it (blur, scale, fade) on a faster curve than the shape's. The wings fold on 0.5 s and unfold on 0.42 s, both critically damped, where every pill resize shared 0.28 s. A settled pause keeps its paused cover through the fold instead of flashing back to full brightness, the redundant black wing layer that faded at the old width is gone, and a peek ends on the fold curve. The lock card's lyric window now glides a line at a time instead of every row jumping a slot, and scrolling the stage by hand lifts every line to a readable brightness until the page follows the song again. PillFoldTests holds the content leaving before the edge reaches it and arriving only once its wing exists; LockCardLyricGlideTests holds the glide travelling exactly one row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The five tab glyphs were, one for one, the set the upstream project ships, so the rail read as somebody else's island. Music is now the Now Playing play mark, Shelf a stack of held things, Clipboard the pasteboard glyph macOS puts on Paste, Translate a speech bubble with a letter the system localizes to the reader's script, and Settings the controls sliders. The chosen tab draws the filled variant and swaps with the system's replace effect, the way a tab bar does. The Settings privacy rows and the Clipboard and Shelf empty states use the same family. TabContractTests holds that every glyph resolves, that no two tabs share one, and that none of the retired set comes back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…line The tab translated English and Russian only, decided by the script typed. Its two column headings are now language menus over sixteen languages — the source detects by default or can be told, a swap exchanges the languages and the text, and the choice is remembered. With the source on Detect and the target on Russian the old rule still holds. Each pair goes to the best engine this Mac has: Apple's Translation framework when it reports the pair installed (fast, and it translates text the model refused as unsafe), the on-device model for its own languages plus Russian, and MyMemory only when the new Translate Online switch is on. It is off by default and recorded as a scope divergence; nothing the Mac can translate itself ever leaves it, and an answer that did carries a globe. Uzbek and Kazakh have no on-device engine, so with the switch off the pane names the language and offers the switch. Apple's recognizer does not know Uzbek, so it is detected by its own letters and words first. The model's responses are capped at three tokens per source character: one English sentence into Uzbek once generated for 218 seconds until its context was full. An open menu now holds the panel the way a drag does, so moving down a language list that hangs below the panel no longer folds it, and the pointer gets 1.2 s to come back once the menu closes. TranslatorTests, LanguageDetectionTests, OnlineTranslationTests and MenuTrackingTests hold the routing, detection, request shape and the hold; TRANSLATOR_LIVE=1 and ONLINE_TRANSLATION_LIVE=1 run the real engines. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…le detecting An inline picker drew the checkmark but had no row to tick while the source detects, and logged an invalid-selection warning on every open. Each language is now a toggle, which a menu draws as the native checkmarked item. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Hovering the rail switched tabs after a 150 ms dwell, so a pointer passing through it flipped panes, and each flip replayed the chosen glyph's fill a third of a second behind the cursor. A click is now the only thing that changes the tab. A hover draws a faint well and nothing else — no dwell, no glyph growing — and the well and the selection land on the frame they happen instead of fading behind a fast pointer. The replace effect on the fill is gone for the same reason. Music wears music.quarternote.3; play.circle read as a button rather than a place. The design's tab-hover dwell is withdrawn by a dated amendment, and NotchMetrics.tabDwell with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
music.quarternote.3 read as busy, as play.circle had read as a button, and the owner asked for the simple one. music.note is the system's own glyph for music, free to every Mac app, and with the other four tab glyphs changed the rail as a whole is no longer the upstream project's. The retired set keeps the other four out. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…'s other findings Translate Online was appended as the last engine whenever the switch was on, so a sentence the model refused, a pair whose language was not downloaded, and any pair with Apple Intelligence off all went to MyMemory. It is now listed only for a pair neither on-device engine offers at all — Uzbek and Kazakh — so no on-device failure can fall through to it, and the pane offers the online switch only where online is what would be used. Below macOS 26 the pane says the system is too old rather than that Russian is not downloaded. The Settings note and the docs say what a request really carries. Detection: a word or two needs 0.95 from the recognizer, which called "Друг" Ukrainian and "Hi" Turkish at 0.60–0.65, and otherwise keeps the old script rule; scripts only one offered language writes decide at any length; і and ы tell Kazakh from Uzbek where the recognizer calls both Kazakh. Swap moves the answer into the field only when it answers what the field holds. Motion: a folded pill gives up its end of the cover and equalizer travel, so opening on a settled pause fades the cover in as before instead of growing it out of the notch's edge; the peek title dissolves with the fold; a folded pill does not shake onto the wallpaper; a track arriving folded does not peek; Reduce Motion keeps the lock card's line change a cut. Menus: counted by identity and held only while the run loop is tracking, so a lost "closed" notice cannot keep the panel open; folding forgets them. TranslatorTests holds exhaustively that no on-device pair lists the online engine (22 failures with the old rule put back); LanguageDetectionTests, MenuTrackingTests and FoldedMorphTests cover the rest. TRANSLATOR_LIVE=1 reran the whole matrix on this Mac. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
What changes for the user
Motion
Icons and the rail
music.note(the owner's choice); the other four are nowrectangle.stack,doc.on.clipboard,character.bubbleandslider.horizontal.3, and the chosen tab shows its filled variant.Translate
Review
An independent review found an online leak: text the Mac could translate itself went to MyMemory after an on-device failure, with Apple Intelligence off, or for languages not yet downloaded. That is fixed and exhaustively tested; the test fails 22 times with the old rule put back. It also found:
All of these are fixed in
022355c.Verification
./scripts/check: all 11 steps pass, 470 tests (4 skipped: live and render, run only on request).PillFoldTests,LockCardLyricGlideTests,TranslatorTests,LanguageDetectionTests,OnlineTranslationTests,MenuTrackingTests, plus additions toTabContractTests. The fold tests failed under mutation of both curves, andNotchMetrics.tabDwellwas removed along with its assertion.TRANSLATOR_LIVE=1ran the full engine matrix on this Mac, andONLINE_TRANSLATION_LIVE=1checked MyMemory.ScrollViewhonours the lyric spring on macOS 27.🤖 Generated with Claude Code