improvement(landing): homepage redesign with live hero and real platform UI feature cards - #5408
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
PR SummaryMedium Risk Overview Hero — Drops the two-panel absolute layout and in-hero New Features — Replaces Supporting — Extracts shared Reviewed by Cursor Bugbot for commit a4f43a9. Configure here. |
Greptile SummaryFull homepage redesign replacing the split-panel hero with a full-width media frame that overlays a live animated two-pane platform loop (chat + draggable workflow stage) over a scaled screenshot. Feature cards migrate from
Confidence Score: 5/5Landing-only redesign with no changes to API routes, auth, or data contracts. The capture harness is properly gated; animation effects clean up correctly. All changes are confined to the (landing) route group and its static assets. The live hero animation uses correct timer/RAF cleanup and motion-preference handling. The capture harness ships with a production guard and an idempotent seed pattern. The one actionable finding is an inaccurate next/image sizes hint on backdrop images in FeatureCard, which causes slightly larger image downloads but has no correctness or runtime impact. apps/sim/app/(landing)/components/features/components/feature-card/feature-card.tsx — the sizes hint on backdrop images could be tightened. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant PL as HeroPlatformLoop
participant Chat as HeroChatLoop
participant Stage as HeroWorkflowStage
participant T as setTimeout chain
PL->>T: runCycle — schedule all ticks
T-->>Chat: "phase=user at 500ms"
T-->>Chat: "phase=thinking at 1400ms"
T-->>PL: "stageOpen=true at 1900ms"
PL->>Stage: "mount with builtCount=0"
T-->>Stage: builtCount 1-5 at 2400-5480ms
T-->>Chat: "phase=reply at 6400ms"
Chat->>Chat: stream reply word by word
T-->>PL: "fading=true at 12240ms"
T-->>PL: runCycle restart at 12500ms
PL->>Stage: remount with next cycleId
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant PL as HeroPlatformLoop
participant Chat as HeroChatLoop
participant Stage as HeroWorkflowStage
participant T as setTimeout chain
PL->>T: runCycle — schedule all ticks
T-->>Chat: "phase=user at 500ms"
T-->>Chat: "phase=thinking at 1400ms"
T-->>PL: "stageOpen=true at 1900ms"
PL->>Stage: "mount with builtCount=0"
T-->>Stage: builtCount 1-5 at 2400-5480ms
T-->>Chat: "phase=reply at 6400ms"
Chat->>Chat: stream reply word by word
T-->>PL: "fading=true at 12240ms"
T-->>PL: runCycle restart at 12500ms
PL->>Stage: remount with next cycleId
Reviews (6): Last reviewed commit: "fix(landing): stop double-seeding query ..." | Re-trigger Greptile |
…orm UI feature cards
…tor window, proportional feature cards - Build card: replace the Mothership chat loop with a static left-to-right support-triage workflow showcase (two triggers converging on a triage agent, fanning out to Linear/Slack/Gmail/Tables) on the hero's solid --surface-3 stage, with the goo cycle loader phasing in the bottom-left corner; the chat animation component stays parked in build-callout/components for reuse - Monitor card: swap the floating logs panel for the REAL platform Logs page captured as a full window (new capture-logs-ui pipeline), framed and positioned identically to the Context card, over a new canyon backdrop - Feature cards scale like Cursor's: media stages are aspect-locked (3:2 desktop, 4:3 stacked) instead of fixed-height, and the UI-window callouts use percentage insets so the whole composition scales proportionally with the browser - Eyebrow chips relocate into the copy column above the title on stacked breakpoints instead of overlapping the full-width media - Extract the hero stage's block card for reuse; export the horizontal smoothstep edge helper; drop the unused formation-graph and logs-table-preview components Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
8e52ff4 to
d1d0c2c
Compare
Matches the token already used by its sibling composer buttons instead of a raw hex hover color.
…ture harness Staging removed the sandbox provider as unused when the academy pages were deleted (#5388), but the landing-preview capture route committed on this branch imports it - the branch failed to compile after rebasing. Restore the lightweight provider with its consumer documented. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The mock hydration state set by the readme-tour-capture route was missing the required requestId/error fields added to HydrationState, breaking the production typecheck.
- hero.tsx: object-top-left isn't a real Tailwind v3 utility, so the crop fell back to center; use object-left-top. - hero-workflow-stage.tsx: byId/builtIds were rebuilt on every render, including every drag pointermove frame; hoist the STAGE_BLOCKS lookup to module scope and memoize builtIds on builtCount. - hero-platform-loop.tsx: prefers-reduced-motion was only read once on mount, so toggling it mid-loop didn't stop the scheduled animation; listen for the media query's change event like BuildChatAnimation does. - landing-preview/page.tsx and readme-tour-capture/[workspaceId]/page.tsx: both are dev/preview-only scaffolds (one explicitly "local-only... delete before committing") that were reachable in production with no auth guard. 404 them outside of production instead of leaving them open.
|
@cursor review |
showFinished (added when wiring up the prefers-reduced-motion change listener) set the finished phase but left fading true if the preference flipped mid reset-fade, leaving HeroChatLoop stuck at opacity-0.
|
@cursor review |
The word-reveal effect only checked prefers-reduced-motion once per showReply transition. If HeroPlatformLoop's showFinished set phase to 'reply' while it was already 'reply' (no re-render, no dependency change), the running stream interval kept ticking at normal speed instead of snapping to the full reply. Listen for the media query's change event, mirroring the fix already applied to HeroPlatformLoop and BuildChatAnimation.
|
@cursor review |
HeroStat's staggered count-up entrance only checked prefers-reduced-motion once on mount, unlike the hero loops in this PR that now listen for the media query's change event. Toggling the preference mid-entrance left the scheduled timers/RAF running instead of snapping to the settled value.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit b0ca3cf. Configure here.
|
Want your agent to iterate on Greptile's feedback? Try greploops. |
seed(queryClient) ran inside a useState lazy initializer, a render-phase side effect that Strict Mode invokes twice. Replace it with a ref guard so the store mutation runs exactly once, still synchronously before first paint. Flagged across three Greptile review rounds.
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit a4f43a9. Configure here.
qc.setQueryData(logKeys.list(...)) requires LogFilters, but the inline seed object had no annotation and timeRange inferred as string, which TypeScript widened past the TimeRange literal union. Failed prod build type-check. Also swap the stray `sandbox` prop back to `embedded` to match Workflow's actual prop name.
…restarts) (#6151) * perf(dev): re-enable the Turbopack dev filesystem cache (5.4x faster restarts) `turbopackFileSystemCacheForDev` has been `false` since #5408 — a landing-page homepage redesign whose description covers hero cards, feature-card aspect ratios, eyebrow chips and a voice-input button color, and never mentions Turbopack, caching, or dev performance. It was collateral, not a decision, and it overrode the Next default (true since v16.1). It is not the flag #6078/#6080 measured. That A/B was `...ForBuild` and its conclusion stands — the build cache is a 3.2x regression and stays off. The two flags look alike and are opposite decisions; both are now commented as such. Measured on `/workspace/[workspaceId]/w`, n=3 per arm, SIGINT between runs: cache OFF 31.4s / 30.1s / 31.9s RSS 9.0-9.8 GB cache ON 5.6s / 5.6s / 5.5s RSS 4.4-5.1 GB 5.4x faster restarts, ~2x less resident memory. Cold compile against an empty cache is unchanged (~32s either way) — the cache only pays back on restart, which is the loop that actually hurts. The cache is unbounded on disk: the abandoned one on this machine had reached 78 GB across 1,848 SST files, and a stale cache is slower to read back, so left alone it erodes the win it exists to provide. `prune-turbopack-cache.ts` runs on `predev` and drops it past a cap (default 20 GB, `SIM_TURBOPACK_CACHE_MAX_GB` to override); `bun run dev:cache:prune` forces it. It never blocks `next dev` on a maintenance failure. Adds a `dev-performance` skill recording the cost model, the reference numbers, and the benchmarking method — including that stopping the server with `kill -9` mid-cache-write discards the cache and makes this exact win read as no win. * improvement(dev): chain the cache prune into dev scripts instead of a predev hook Review read the root `bun run dev` path as bypassing the `predev` hook and so never capping the newly-enabled cache. Turbo does fire `pre*` hooks — verified live, the run prints the prune before `next dev` — but the concern is fair in that the guarantee rested on package-manager lifecycle semantics that are invisible at the call site. Chaining it explicitly removes the question entirely: every `dev` variant now runs `bun run dev:cache:cap && …`, which holds on any invocation path, is visible in the command itself, and drops the three duplicated `predev:*` entries for one shared script. Verified on both paths — direct `bun run dev` and root `turbo run dev`, the latter printing: sim:dev: $ bun run dev:cache:cap && next dev --port 3000 sim:dev: $ bun run ../../scripts/prune-turbopack-cache.ts * docs(dev): document cache-corruption recovery, the cost of enabling the cache Stress-tested the failure mode rather than assuming it: deliberately corrupting an SST block makes Turbopack abort with a FATAL panic — it does not self-heal. FATAL: An unexpected Turbopack error occurred. Cache corruption detected: checksum mismatch in block 4 of 00000221.sst `bun run dev:cache:prune` and restart fixes it; verified the canvas serves 200 again afterwards. Documented in the skill and in the script's header, since the symptom is a hard crash and the remedy is not guessable. This is the honest cost of turning the cache on. It is worth paying — a 5.4x faster restart against a rare, loud, single-command failure — but it should be written down rather than discovered. Worth distinguishing from the adjacent case: an ordinary hard kill does *not* corrupt the cache. Turbopack discards a partially-written cache and rebuilds it silently, which is exactly why a `kill -9`-based benchmark reads as "no cache win" (noted in the benchmarking section). * refactor(dev): drop the dev-performance skill, keep its findings at the code A whole skill was too much for what this is. The parts that are load-bearing — why the two lookalike cache flags are opposite decisions, the measured numbers, the corruption remedy, and the benchmarking trap — now live in the config and script they describe, where someone changing the flag actually reads them. The trap is the piece worth keeping: `next dev` compiles on demand so startup time is meaningless, and stopping the server with `kill -9` makes Turbopack discard a partially-written cache and rebuild silently — which reads as 'the cache does nothing' and is how this flag stayed wrong for a month. Dropped rather than relocated: generic advice that was not specific to this repo (antivirus, Docker-on-macOS, orphaned processes) and a measured no-op (`optimizePackageImports` for lucide-react changed nothing, 31.6s vs 31.7s). * docs(dev): record the measured cost and concurrency behaviour of cache pruning Stress-tested the maintenance path rather than assuming it is free. Cost: the size walk is ~30ms on a real cache and ~85ms at 2,000 files — under 2% of a 4.2s warm restart, and invisible against a cold one. It runs before every dev start, so it needed to be cheap; it is. Concurrency: pruning while a dev server is live (which happens when a second server is started from the same checkout) does not crash it. The running server keeps its in-memory state and kept serving HTTP 200 with zero panics. It does stop persisting for the rest of that session, so its next start is cold once — verified recovering at 23.4s then 4.5s. Worth writing down because the directory silently never reappears mid-session, which looks like a bug if you go looking. The cap is a backstop, not routine: a normal session sits at 1-2 GB against a 20 GB default. * fix(dev): cap every app's Turbopack cache, not just apps/sim `apps/docs` is a Next app too (`next dev --port 3001`) and overrides nothing, so it uses the Next default where the dev filesystem cache is on. It already had an uncapped 1.1 GB cache here, and the root `bun run dev` (`turbo run dev`) starts it — so a teammate using the documented command was accumulating a cache nothing would ever prune. The script now resolves its target from the working directory instead of hardcoding `apps/sim`, and each app chains its own cap. Per-app rather than one sweep on purpose: a single pass would let one app's dev start delete a cache another app is holding open, which costs that session its persistence. Verified both: `apps/sim` and `apps/docs` each report and cap their own 1.1 GB cache, and both dev servers start clean (`Ready in 299ms` / `229ms`, docs serving). * refactor(dev): drop dev:cache:prune in favour of the existing dev:clean `dev:cache:prune` duplicated `dev:clean`, which already existed in `apps/sim` and does strictly more (`rm -rf .next/dev/cache` covers the Turbopack cache plus the fetch and image caches). Two commands for one job is worse than one, and the docs pointed at the newer, narrower of the two. Removes it from both apps and gives `apps/docs` the `dev:clean` that `apps/sim` already had, so the recovery command is the same everywhere. `dev:cache:cap` stays — it is the chained step, used by more than one dev variant, and naming it keeps the relative script path out of each command. Verified `dev:clean` is a real remedy: corrupt a cache block, run it, restart — canvas serves 200 with no panic. Also corrects an overstatement. A damaged cache does not *always* abort Turbopack; whether it panics depends on whether the damaged region is read, so it is not reliably reproducible. Both notes now say "can abort" and give the same remedy either way.
What this is
The landing homepage redesign, rebased onto the latest
staging(clean linear history; the one conflict —partners/page.tsx, deleted on staging by #5388 — resolved by keeping the deletion).Commit 1 — homepage redesign
Live hero with the real platform two-pane loop, real-UI feature cards, and the
(landing)route group updates.Commit 2 — feature-card iteration
--surface-3stage, goo cycle loader in the corner. Non-brand icon tiles use the hero's greyscale ramp; brand colors only on real third-party marks.capture-logs-uipipeline mirroring the knowledge capture, seeded run table) over a new canyon backdrop, positioned identically to the Context card.3:2desktop /4:3stacked) instead of fixed-height, and UI-window callouts use percentage insets — the whole composition scales uniformly with browser size. Verified at 1440/1280/1120/768/375 with no overflow.StageBlockCardfor reuse, exported the horizontalsmoothStephelper, removed the unusedformation-graphandlogs-table-previewcomponents.build-callout/components/build-chat-animation) is committed but intentionally unwired — parked for reuse on another surface.Review notes
apps/sim/app/landing-preview/**(login-bypass preview + capture harness) is included from the redesign commit — it powers the UI-capture pipeline; flagging in case it should be gated or dropped before prod.