Chore/UI landing parity - #7
Conversation
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
There was a problem hiding this comment.
Pull request overview
Updates the web UI to align the Home + Job pages with a new “landing parity” visual system, primarily by moving from inline styles to a shared CSS-driven design and adding new ambient/hero effects.
Changes:
- Refactors
Home,JobPage,Layout,TelemetryPanel, andAgentTimelineto use sharedsf-*classnames instead of inline styles. - Adds a new global CSS visual system (tokens, layout, animations, job page styling, telemetry styling) in
index.css. - Updates the Bun lockfile format metadata (
configVersion).
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| bun.lock | Adds configVersion metadata to the lockfile. |
| apps/web/src/pages/JobPage.tsx | Converts job UI to new class-based layout + hero lighting + restyled states. |
| apps/web/src/pages/Home.tsx | Implements new hero layout, particle/parallax effects, and class-based form styling. |
| apps/web/src/index.css | Introduces the new global theme + layout + animation + page-specific styling. |
| apps/web/src/components/TelemetryPanel.tsx | Restyles telemetry UI and switches bars to <progress> with CSS variants. |
| apps/web/src/components/Layout.tsx | Moves layout/nav/footer styling to shared CSS classes. |
| apps/web/src/components/AgentTimeline.tsx | Moves timeline styling to shared CSS classes. |
Comments suppressed due to low confidence (1)
apps/web/src/pages/JobPage.tsx:397
Try Againuseswindow.location.href = "/", which forces a full page reload in an SPA and bypasses react-router navigation (and can be slower / lose client state). Prefer using a<Link to="/">oruseNavigate()so the app navigates client-side while still unmounting this page and closing the stream connection.
<div className="animate-fade-in sf-job-inline-alert is-error sf-job-alert-center sf-job-failed-wrap">
<p className="sf-job-alert-title">
Generation Failed
</p>
<p className="sf-job-alert-text sf-job-alert-text-spaced">
{stream.jobError ?? "An unexpected error occurred"}
</p>
<Button variant="secondary" onClick={() => window.location.href = "/"}>
Try Again
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .sf-particle { | ||
| position: absolute; | ||
| border-radius: 50%; | ||
| background: #fff; | ||
| box-shadow: 0 0 8px 1px rgba(255, 255, 255, 0.4); | ||
| transform: translate( | ||
| calc(var(--parallax-x) * var(--depth, 1)), | ||
| calc(var(--parallax-y) * var(--depth, 1)) | ||
| ); | ||
| transition: transform 1.8s ease-out; | ||
| animation-name: sf-twinkle; | ||
| animation-iteration-count: infinite; | ||
| animation-direction: alternate; | ||
| animation-timing-function: ease-in-out; | ||
| } |
There was a problem hiding this comment.
The new particle/parallax effects add continuous animations (e.g., sf-twinkle + long transition on .sf-particle) but there is no prefers-reduced-motion handling anywhere in the stylesheet. Please add a @media (prefers-reduced-motion: reduce) block that disables these animations/transitions (and other new background animations) to avoid motion-sickness and meet accessibility expectations.
| useEffect(() => { | ||
| const root = containerRef.current; | ||
| if (!root) return; | ||
|
|
||
| const setFromPoint = (x: number, y: number) => { | ||
| const width = window.innerWidth || 1; | ||
| const height = window.innerHeight || 1; | ||
| const moveX = (x - width / 2) / (width / 2); | ||
| const moveY = (y - height / 2) / (height / 2); | ||
|
|
||
| root.style.setProperty("--cursor-x", `${x}px`); | ||
| root.style.setProperty("--cursor-y", `${y}px`); | ||
| root.style.setProperty("--parallax-x", `${-moveX * 40}px`); | ||
| root.style.setProperty("--parallax-y", `${-moveY * 40}px`); | ||
| }; | ||
|
|
||
| setFromPoint(window.innerWidth / 2, window.innerHeight / 3); | ||
|
|
||
| const onMouseMove = (event: MouseEvent) => { | ||
| setFromPoint(event.clientX, event.clientY); | ||
| }; | ||
|
|
||
| window.addEventListener("mousemove", onMouseMove, { passive: true }); | ||
| return () => window.removeEventListener("mousemove", onMouseMove); | ||
| }, []); |
There was a problem hiding this comment.
The mousemove handler updates multiple CSS variables on every mouse event, which can cause unnecessary style recalculation and jank on high-frequency pointer movement. Consider throttling via requestAnimationFrame (or a small debounce) and/or using pointermove with a coarse-pointer / reduced-motion guard so the effect is lighter on CPU/GPU.
No description provided.