Skip to content

feat(theme): add the page-enter and content-enter arrival animations - #896

Open
gabriel-lisboa-azion wants to merge 2 commits into
mainfrom
feat/theme-arrival-animations
Open

feat(theme): add the page-enter and content-enter arrival animations#896
gabriel-lisboa-azion wants to merge 2 commits into
mainfrom
feat/theme-arrival-animations

Conversation

@gabriel-lisboa-azion

Copy link
Copy Markdown
Collaborator

Summary

  • animate-page-enter — the route transition. Starts one --layout-boundary-inline to the left of where it lands and travels right while fading up, so a page reads as arriving from the nav row that was clicked; a plain fade has no origin and a right-side arrival reads as going back. Retune per shell with --page-enter-distance.
  • animate-content-enter — content settling inside a page that is already on screen. Rises a hair instead of travelling, and takes a --content-enter-delay stagger (backwards fill is load-bearing: without it a delayed follower paints its landed state and then jumps back).
  • Neither fills forwards, deliberately — page-enter's box is usually the scroll container, and a lingering translate would make it a containing block for any position: fixed descendant.
  • webkit-motion-polish documents both, plus the failure they exist to prevent: a page arrives once, so a mount-time entrance inside a page whose route transition is still running lock-steps with it into one diagonal move.

How to test

  1. node packages/theme/src/scripts/build-tokens.mjspackages/theme/dist/v4/globals.{css,scss} diff is exactly the two --animate-* entries (light + dark) and the two @keyframes; nothing else moves.
  2. Probe that the utilities actually emit CSS (they are dead-silent if they do not — see .claude/rules/styling.md), through the v4 compile API with a bogus class as the control:
    compile(globals.css).build(['animate-page-enter','animate-content-enter','totally-bogus-control-class'])
    
    → the first two emit animation: var(--animate-page-enter|content-enter), the control emits nothing.
  3. node packages/webkit/scripts/build-catalog.mjstokens.animations is 21 and contains both.
  4. cd packages/webkit && node --test "test/**/*.test.mjs" → 115 pass.

Notes

  • Timing is moderate-02 + productive-entrance for both — the pairing the system already uses for a panel of content arriving, so a page and the components on it move as one system.
  • catalog.json is rebuilt in the same PR: until it carries the two names, validate-spec-compliance rejects animate-page-enter in a component.

The two entrances an app shell needs, as a pair. page-enter is the route
transition: it starts one --layout-boundary-inline to the LEFT of where it lands
and travels right while fading up, so a page reads as arriving FROM the nav row
that was clicked — a plain fade has no origin and a right-side arrival reads as
going back. content-enter is content settling inside a page already on screen, so
it rises a hair instead of travelling, and takes a --content-enter-delay stagger
(with backwards fill, or a delayed follower would paint its landed state first).

Neither fills forwards: page-enter's box is usually the scroll container, and a
lingering translate would make it a containing block for any fixed descendant.
Documents both utilities and their knobs, and the failure they exist to prevent:
a page arrives once, so a mount-time entrance inside a page whose route
transition is still running lockesteps with it into one diagonal move (identical
opacities frame for frame is the tell). Adds that shape and the two-shells-per-
screen variant to the silent-failure table. catalog.json rebuilt so the two
animations reach the MCP and validate-spec-compliance.
@gabriel-lisboa-azion
gabriel-lisboa-azion force-pushed the feat/theme-arrival-animations branch from 0721c8c to 979583c Compare August 17, 2026 12:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant