Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
AI review status for this pull request.
|
There was a problem hiding this comment.
Approval of this spec change waits on an engineering owner's decision on the proposed motion direction in spec:AST-108 FR3a, FR8, DEC-3 and DEC-4. Those clauses replace each gesture's measured release spring with one spring per character at the default, move touch entrances and the animated-layout glide onto the token table, and add 'fluid'. That decision also covers the amendments they need to AST-108 FR1/FR3/FR5, AST-094 FR1/FR4 and AST-105 FR4. An engineering owner records it by commenting /approve-spec <full head SHA> on this pull request; the author may do so as an engineering owner.
Separately from that decision, the record needs these fixes:
- The FR8 verification row (line 264) still fails "a glide that plays a curve" and "a touch role off its measured value", although FR8 and FR3a now have the glide and touch entrances play the token table.
- The settle-time definition (lines 187–190) does not match 347 ms for
springs.menuOpen: by "stays within 1 %" the spring settles at about 324 ms, where the fluid entrance curve is about 6 % off, so state the envelope-bound window the 347 ms comes from. - FR1, FR3 and FR5 and their verification rows still say three characters, measured springs at
'standard', and unchanged existing themes, so rewrite them here (marked proposed) instead of noting that approval amends them. - The Current-state impact should also list
architecture:theme-authoring-contractINV15, AST-094 FR1 and AST-105 FR4 as records to amend, not only AST-094 FR4. - The Reduce Motion bullet (lines 205–206) lands every non-touch release at once, but the reduced-motion design record cross-fades a trackpad-started release on a coarse primary pointer.
[Automated review]
| | FR5 | Theme tests with the released configurations | a `MotionScaleConfig` theme, explicit tokens, an extending theme; an adaptation rule that sets `tempo` or `character` | changed output for an existing theme, or a knob that beats an explicit field, fails | | ||
| | FR6 | Server-render tests and import checks | a server render with each `reducedMotion`; importing the theme and motion modules; `'always'` with the person's setting off, across components that key on `prefers-reduced-motion`; a nested theme under an `'always'` theme | a DOM access at import or on the server, theme CSS emitted for `'system'`, a hydration change, or a component style, script reader, or `when: {motion}` rule that ignores the root mark under `'always'`, or a nested theme that restores motion under an ancestor's `'always'`, fails | | ||
| | FR7 | Docs review | each listed doc | a doc without the knobs, the fixed list, or the precedence fails | | ||
| | FR8 (proposed) | Theme unit tests over generated CSS, resolver tests, and browser frame capture | `'fluid'` at each `tempo` bound and 1; each table row; a glide under a mouse and a finger; Reduce Motion under a coarse and a fine pointer | a fluid curve more than 2 % of the travel off its spring, a CSS exit, fade, or duration token that differs from `'standard'`, a touch role off its measured value, a glide that plays a curve, or a spring under Reduce Motion fails | |
There was a problem hiding this comment.
This row still fails "a touch role off its measured value" and "a glide that plays a curve", but FR8's token table (line 173), the impact line at 242–244 and FR3a (103–107) now have the glide play --ease-move and non-gesture touch roles play the token table. Suggest "a glide that plays a spring" and "a fluid gesture spring off its measured value".
| - A fluid curve is its spring's travel from rest over the spring's 99 % | ||
| settle time (the time after which it stays within 1 % of its travel: | ||
| 347 ms for `springs.menuOpen`, 528 ms for `springs.settle`), fitted as a | ||
| cubic Bézier within 2 % of the travel at every point. The spring's |
There was a problem hiding this comment.
By "the time after which it stays within 1 % of its travel", springs.menuOpen (response 0.32 s, damping ratio 0.8) settles at about 324 ms. 347 ms is the decay-envelope bound the spring model's settle time returns. Over 324 ms, cubic-bezier(0.31, 0.35, 0.12, 1.12) is about 6 % off the spring, beyond the 2 % bound, so a test built from this definition rejects the table's curve. Define the window as the envelope bound, or state 347 ms without the gloss.
| - FR3a and FR8 are proposed. When approved, they amend FR1 (a fourth | ||
| `character`), FR3 (at `'standard'`, a gesture plays the standard gesture | ||
| spring, not its measured one, and a non-gesture motion plays the token | ||
| table on every pointer), and FR5 (an existing theme's gesture springs and | ||
| touch timed motion change with that default); `spec:AST-094` FR4 states the | ||
| pointer side. |
There was a problem hiding this comment.
FR1 (line 65), FR3 (90–92: "every role plays its measured value exactly"), FR5 (134–135: "springs included") and their verification rows (257, 261) still say the opposite of FR8's standard gesture spring. Approving this head would approve both. Rewrite those clauses and rows here, marked proposed.
| - `defineTheme` does not accept `'fluid'` yet. It needs `spec:AST-105` FR4 to | ||
| time the glide from the theme's tokens, the animator to read the theme's | ||
| knobs at each gesture's start, and the character's curve table to set | ||
| `--ease-entrance` and `--ease-move` to different values. Today the glide | ||
| plays `springs.settle` at every character, no spring reads the knobs, and | ||
| no Core component reads `--ease-entrance` or `--ease-move`. |
There was a problem hiding this comment.
architecture:theme-authoring-contract INV15 (three characters), AST-094 FR1 ("MUST default to the measured native value") and AST-105 FR4 (the glide reads springs.settle) also need amending for FR3a and FR8. Please list them with the change each needs.
| - Reduce Motion is the same at every character (`design:reduced-motion` | ||
| DR1–DR3): no spring plays and nothing travels; a coarse primary pointer | ||
| gets a cross-fade of 200 ms or less, any other pointer an immediate | ||
| change; a throw still coasts, and a release that snaps, dismisses, or | ||
| pages cross-fades after a touch drag and lands at once otherwise. |
There was a problem hiding this comment.
"lands at once otherwise" departs from the reduced-motion design record, which has a release a trackpad started follow DR2 (cross-fade) on a coarse primary pointer. Suggest "cross-fades after a touch drag or under a coarse primary pointer, and lands at once otherwise", or cite DR2 and DR3 without restating them.
Main's #9964 rewrote AST-108 FR1's character bullet, which the fluid rework changes too.
`fluid` is a fourth column of the token table: its own entrance and move curves and its own medium duration bases, all scaled by tempo. It is not fitted to the measured springs, and no option plays a platform-measured curve for tap-started motion. - Fluid's medium bases take the next value of the released scale: 410, 550 and 730 ms for medium-min, medium and medium-max, about a third longer. The fast and slow tiers keep their released values. - Its entrance curve, cubic-bezier(0, 0, 0, 1), starts at speed and slows over a long tail. Its move curve, cubic-bezier(0.2, 0, 0, 1), starts from rest, so an element already on screen does not jump. Neither overshoots. - Busy loops keep their periods at fluid, and a CSS part timed with a spring keeps the spring's settle time. The decision point: a character sets no spring (DEC-4, FR3). Gestures play the measured spring roles scaled by tempo, with their bounce unchanged, and character touches only tokens, so one scale coordinates springs and curves. This removes FR3's per-role bounce weights. No spring reads character today, so no shipped motion changes. Also: FR3a goes, since AST-094 FR45 owns which motion springs. FR1, FR2 and FR3 are rewritten in place and marked proposed. The Reduce Motion bullet follows design:reduced-motion DR2 and DR3. The current-state impact names AST-094 FR4, FR45 and DEC-15 and the theme authoring contract's INV15 as records to amend. Writing rubric results: - R1 narration: none. The only hits are the "(proposed)" labels on FR1, FR2, FR3, FR8, DEC-3 and DEC-4, which mark pending owner decisions. - R2 research in the record: none. The value reasoning is two sentences in DEC-3. - R3 evidence naming a change: none. - R4 rejected alternatives: one line each, inside DEC-3 and DEC-4. - R5 pull request or issue references: none in the record. - R6 answered open questions still listing options: none; OQ1 stays open. check:knowledge: aligned. Prettier: clean.
There was a problem hiding this comment.
Approval of this spec change waits on an engineering owner's decision on the proposed spec:AST-108 FR1, FR2, FR3, FR8, DEC-3 and DEC-4. They add 'fluid' as a fourth character, with its own entrance and move curves and medium duration bases. They also make character set no spring. Together they change AST-108 FR1–FR3 and reverse AST-094 FR4, FR45, DEC-15 and DEC-26 on gesture springs, as those stand on main. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner.
Whatever that decision, these need fixing:
- The pull request description still describes the earlier draft (curves fitted to the measured springs, a gesture spring per character, FR3a, no duration change), which DEC-3 and DEC-4 now reject, so rewrite it from the current record, writing rubric results included.
- AST-094 DEC-26 and the FR45 verification row, which fails a gesture spring that ignores
character, contradict the proposed FR3 but are missing from the Current-state impact, so amend them here along with FR4, FR45 and DEC-15, or at least list them, and drop the bounce offset that #9915 re-states. - FR4's busy-loop clause ("the duration their theme sets before
temposcales it") andcomponent:SkeletonFR4 would let'fluid'stretch Skeleton's pulse from 550 to 730 ms, which FR8 forbids, so reword FR4 to read the duration scale's base and list Skeleton FR4 and INV15's loop sentence for amendment. - The Reduce Motion bullet in FR8 leaves out the reduced-motion DR2 rule that an in-place value change applies at once on any pointer.
[Automated review]
| - A busy loop keeps its period at `'fluid'`: it reads the base its theme's | ||
| duration scale sets, never a character's base (FR4). |
There was a problem hiding this comment.
FR4 above ("which read the duration their theme sets before tempo scales it") and component:Skeleton FR4 ("--duration-medium-max as the theme sets it before tempo scales it") still read the character-set base, so at 'fluid' they give Skeleton a 730 ms half-pulse, which this bullet forbids. Suggest rewording FR4 to "the duration their theme's duration scale sets, before character and tempo", and listing Skeleton FR4 and INV15's loop sentence below.
| - Reduce Motion is the same at every character (`design:reduced-motion` | ||
| DR1–DR3): no spring plays and nothing travels. A transition cross-fades | ||
| in 200 ms or less when the primary pointer is coarse or the release of a | ||
| touch drag starts it, and changes at once otherwise; a throw still | ||
| coasts. |
There was a problem hiding this comment.
reduced-motion DR2 exempts an in-place value change ("under reduced motion it applies at once on any pointer"), but this bullet makes every transition cross-fade under a coarse pointer. Suggest adding "an in-place value change applies at once (DR2)", or citing DR1–DR3 without restating them.
| - FR1, FR2, FR3, FR8, DEC-3, and DEC-4 are proposed. `spec:AST-094` FR4, | ||
| FR45, and DEC-15 still give `character` a bounce offset through per-role | ||
| weights, and `architecture:theme-authoring-contract` INV15 still lists | ||
| three characters that set only curves; each is amended to match. |
There was a problem hiding this comment.
AST-094 DEC-26 ("The theme's character shapes those springs and its tempo scales them") and the FR45 verification row ("a gesture's spring that ignores character or tempo ... fails") also contradict FR3 and DEC-4, but they are not listed here. Against the FR3 row above, no implementation can pass both.
A preview for the fluid column's review: the same motions, an expand, the glide of the rows after it, and a menu, under the standard and fluid columns side by side at phone width, with a tempo switch (0.75, 1, 1.5). Open plays them in both columns at once. defineTheme does not take 'fluid' yet, so the story writes each column as explicit tokens times the tempo. The expand and the glide play --ease-move over --duration-medium-min; the menu enters on --ease-entrance over the same duration and leaves on --ease-exit over --duration-exit. Under Reduce Motion they change at once.
PR Analysis Report
Generated by PR Enrichment workflow | View current CI run |
There was a problem hiding this comment.
Approval of this spec change waits on an engineering owner's decision on the proposed spec:AST-108 FR1, FR2, FR3, FR8, DEC-3 and DEC-4, which add 'fluid' as a fourth character with its own curves and medium duration bases and make character set no spring, changing AST-108 FR1–FR3 and reversing AST-094 FR4, FR45, DEC-15 and DEC-26 as they stand on main. An engineering owner records the decision by commenting /approve-spec <full head SHA> on this pull request; the author may do so if they are an engineering owner.
Whatever that decision, these need fixing:
- The description still describes the earlier draft (curves fitted to the measured springs, a gesture spring per character, FR3a, no duration change), which DEC-3 and DEC-4 now reject, and its Scope list still says the pull request contains specification records only although it now adds the
ThemeMotionCharacterstory, so rewrite it from the current record and mention the story. - AST-094 DEC-26 and the FR45 verification row, which fails a gesture spring that ignores
character, contradict the proposed FR3 but are missing from the Current-state impact, so amend them here along with FR4, FR45 and DEC-15, or at least list them. - FR4's busy-loop clause ("the duration their theme sets before
temposcales it") andcomponent:SkeletonFR4 would let'fluid'stretch Skeleton's pulse from 550 to 730 ms, which FR8 forbids, so reword FR4 to read the duration scale's base and list Skeleton FR4 and INV15's loop sentence for amendment. - The Reduce Motion bullet in FR8 leaves out the reduced-motion DR2 rule that an in-place value change applies at once on any pointer.
[Automated review]
People using a theme with
character: 'fluid'get motion that feels like the native platform: a flick keeps its speed into a measured spring, and entrances and moves take curves fitted to those springs. Every other character gets the same split, with its own curves and its own gesture spring.Draft, stacked on
main. This pull request introduces'fluid'as the fourthcharacter: the type value, both tables, and the gesture springs. It depends on #9663, which makes the theme'scharacterandtemporeach the glide; it does not touch #9663's branch. Off the release path: this spec merges on its own, no release gate, plan, or changeset depends on it, and the build lands whenever it is ready.Exact decision needed
What each
characterpresets: the token table that non-gesture motion plays, and the spring that gesture motion plays, and what'fluid'puts in both.Existing authority searched
spec:AST-108FR1–FR5, FR4a, DEC-1: three characters reach--ease-entrance,--ease-move, and the springs' bounce; exits and--ease-standardnever change;temposcales every duration.spec:AST-105FR4, FR8, FR9: the glide, swap, and edge reveal share one motion.spec:AST-094FR4, FR36–FR38, FR43: the measured springs, the release settle, and gestures on every pointer. Its pointer-side wording is written in a separate pull request.design:reduced-motionDR1–DR3.motion/uikit/springs.ts,theme/themeMotion.ts(CHARACTER_EASE),theme/motionKnobs.ts,motion/animatedLayout.ts(the glide's CSS twin).characterandtempo; adds no character); feat(core): the animator's springs follow the theme's tempo #8677 (the animator readstempoandcharacterat each motion's start).Decision
Gesture motion plays a spring; other motion plays the tokens (FR3a). On every pointer and at every character, the settle, snap, dismissal, or page after a drag, swipe, flick, or pan starts from the gesture's velocity on a spring.
charactersets its bounce and response;temposcales its duration. Every other timed motion, the glide, swap, and edge reveal included, plays the character's easing token over its duration token. Finger tracking, momentum, and the rubber band stay fixed.Each character is two tables (FR8).
--ease-entrancecubic-bezier(0, 0, 0.2, 1)cubic-bezier(0.24, 1, 0.4, 1)cubic-bezier(0.3, 1.2, 0.5, 1)cubic-bezier(0.31, 0.35, 0.12, 1.12)(menu spring's shape)--ease-movecubic-bezier(0.23, 0.17, 0.2, 0.99)(settle spring's shape)--ease-exit--ease-standard--duration-*How the fluid curves are made. Each is its spring's travel from rest over the spring's 99 % settle time (347 ms for the menu spring, 528 ms for the settle spring), fitted as a cubic Bézier: maximum error 1.9 % and 1.4 % of the travel. A cubic Bézier keeps the token's current form and works in every browser;
linear()would add nothing visible at that error.How the gesture springs are made. From rest, each crisp, standard, and expressive spring stays within 1 % of its travel after
--duration-medium-min(310 ms), the glide's length. Standard does not overshoot, crisp is overdamped, expressive overshoots about 1.5 %, as its curve does.Reduce Motion is the same at every character: no spring, no travel; a cross-fade of 200 ms or less under a coarse pointer, an immediate change otherwise; a throw still coasts.
No engine switch. The glide, swap, and edge reveal are non-gesture motion, so at
'fluid'they play fluid's spring-shaped move token over--duration-medium-min, the same way they play every other character's token (spec(AST-105, AST-108): glides follow the theme's character and tempo; the measured spring becomes character 'native' #9663). No character switches non-gesture motion to the spring engine.Rejected alternatives
tempoalready owns length.Claim scope and non-goals
--ease-exit,--ease-standard, the duration scale, the press clocks, or the fixed list.spec:AST-094's pointer wording is out of scope here.Evidence and implementation relationship
Values computed from the springs' closed forms (SwiftUI duration and bounce, response and damping ratio), settle time at 1 % of travel, and a cubic-Bézier fit minimizing the maximum error. Engine requirement for #8677: the knob reader must accept
'fluid'; at'fluid'a gesture plays its measured spring, and at the other characters it plays the character's normalized spring, both from the gesture's velocity; no non-gesture motion switches engines.themeMotion.ts's curve table must let--ease-entranceand--ease-movediffer.Writing rubric results
Scope
Validation
pnpm check:knowledge: alignedgit diff --check: clean