Loaded content now settles in: library cards and rows, checker issue rows,
assistant suggestions and past conversations rise in with a short stagger on
first appearance only; new assistant messages and "Thinking…" rise in while
history stays put; a newly made document fades up from 96% with its accent
ring fading in.
Resume thumbnails keep the last drawn page of the same resume up while a new
one renders, so edits and return visits no longer drop to a placeholder. The
builder's first preview render paints hidden under the placeholder pages and
fades in; the PDF viewer reserves an A4 slot and holds its overlay until a
page has painted. The ATS checker ring fills on first reveal, ring colour
blends across the threshold, and report and insights bars grow from their
baseline.
Hand-rolled pulsing placeholders become the static Skeleton, shaped like the
view that is loading (documents grid or list, applications views, insights,
API keys). ENTER_CLASS and stagger() live in libs/motion.ts.
Pathname changes after the first load now run a typed `page` view transition: the old page fades out over 140ms and the new one fades up 6px over 200ms on the house tokens. Search-param and hash changes, the first load and browsers without view-transition types stay instant. The app nav, settings nav and auth logo are named so they hold still.
The auth card's load-time entrance is removed. Applications views, the Documents grid/list switch and Calendar month changes now enter with a short fade (months slide from the direction of travel), only after the user switches.
Set Tailwind's default transition duration and curve to --d1/--ease so
bare transition-* utilities run quick on the house curve. Mirror the
motion tokens in libs/motion.ts (EASE, EASE_MOVE, D1-D3, EXIT) and move
app UI off ease-out-strong and hand-typed 150/300ms durations; the
landing page keeps --ease-out-strong.
Give snapping hover and focus states a transition, slide progress fills
with translate instead of animating width, keep selection outlines'
width and style constant so they fade from transparent instead of
flashing dark, and drop the unused agent-prompt-marquee keyframes.
- The score ring (live checks only, easing to each new score), the verdict,
and Issues · Job match · Writing tabs.
- Issues: numbered cards with category, explanation and fix, pinned to their
lines on the page with warn pins and wavy underlines. One-step fixes apply
with undo; the rest open the field in Write. Show on page, and Ignore (Keep
for the two-column issue), stored with the resume. Category rows below, open
when they need attention. "Also check the exported PDF" reports in a toast.
- Job match reads the linked application's posting, or a pasted one that can
be saved as an application. Missing terms ask where they belong (Add to
Skills) or can be hidden; covered terms light up their entries on the page.
- Writing: an opt-in AI review that says what it sends. Rewrites of bullets
and paragraphs arrive as proposals: struck-through old text and highlighted
new text on the page, numbered markers, Accept, Reject, Accept all, A/R and
arrow keys, one undo step. Out-of-date proposals can't be applied.
- "What a person sees / What a parser reads": the parser view extracts the
text of the PDF on the page, in reading order, flagging issue lines.
- Phones step through issues on the page; tablet pins open the drawer.
- The builder's ATS section and its deep-check UI are gone.
Audit every animation in the app and shared UI primitives against a
frequency-first motion bar: keyboard and high-frequency actions no longer
animate, remaining motion uses interruptible CSS transitions with shared
easing tokens, and redundant animation code is removed.
UI primitives (@reactive-resume/ui)
- Dialog, alert dialog, popover and tooltip move from tw-animate keyframes
to Base UI data-starting/ending-style transitions; menus, popovers and
tooltips skip motion when opened from the keyboard (data-instant).
- Dialog gains an `instant` prop; the command palette uses it.
- Accordion animates its real panel height; caret rotates instead of
swapping icons.
- Menu backdrop blur moves onto the popup so it no longer snaps in after
the fade; context menus and comboboxes fade only.
- Sidebar collapse uses the strong ease-out curve and snaps on Cmd+B.
- Toast, sheet, checkbox, tabs, toggle, inputs and message scroller get
tokenised easing, correct transition properties and press feedback.
- Tabs no longer squeeze a trigger narrower than its label.
- Spinners keep spinning under prefers-reduced-motion.
Web app
- Remove the default route view transition and page-entrance slides.
- Add EASE_OUT_STRONG for Motion; replace built-in "easeOut" everywhere.
- Switch LazyMotion to domMax so layout and Reorder animations run.
- Builder: consolidate 12 section list files into one ItemsSection,
opacity-only list rows with popLayout, instant Cmd+0, faster dock zoom,
crossfade that no longer dips, transform-based progress bars.
- Dashboard: keep previous results while sorting/filtering, no empty-state
flash, uncontrolled sidebar (no network round trip on collapse), calmer
resume card tilt, no stacked hover wrappers.
- Settings: drop entrance/stagger wrappers and ActionButton.
- Agent: CSS marquee paused on hover; thread switches keep the layout.
- Homepage: fix invalid transition declarations, CSS spotlight drift,
scroll-hiding header without a JS spring, tokenised curves.
- Theme switches change every color at once.
- Remove SSR-only useIsClient guards from the SPA.
Docs: rewrite the DESIGN.md animation section around the new tokens.