Skip to content

improvement(landing): homepage redesign with live hero and real platform UI feature cards#5408

Open
andresdjasso wants to merge 4 commits into
stagingfrom
improvement/landing-homepage-blog
Open

improvement(landing): homepage redesign with live hero and real platform UI feature cards#5408
andresdjasso wants to merge 4 commits into
stagingfrom
improvement/landing-homepage-blog

Conversation

@andresdjasso

@andresdjasso andresdjasso commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

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

  • Build card: static left-to-right support-triage workflow showcase (Gmail + Slack triggers → Claude triage agent → Linear / Slack / Gmail / Tables fan-out) rendered from the hero's block kit on a solid --surface-3 stage, goo cycle loader in the corner. Non-brand icon tiles use the hero's greyscale ramp; brand colors only on real third-party marks.
  • Monitor card: the REAL platform Logs page captured as a full window (new capture-logs-ui pipeline mirroring the knowledge capture, seeded run table) over a new canyon backdrop, positioned identically to the Context card.
  • Proportional scaling (Cursor-style): feature-card media stages are aspect-locked (3:2 desktop / 4:3 stacked) 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.
  • Mobile: eyebrow chips relocate into the copy column above the title on stacked breakpoints instead of overlapping the media.
  • Extracted StageBlockCard for reuse, exported the horizontal smoothStep helper, removed the unused formation-graph and logs-table-preview components.
  • The Mothership chat + goo-morph animation (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.
  • Landing-only changes; no API routes, contracts, or platform code touched.

🤖 Generated with Claude Code

@vercel

vercel Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 7, 2026 8:35pm

Request Review

@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

PR Summary

Medium Risk
Large, landing-only UI change with new above-the-fold client animation and priority hero imagery; no auth or API impact, but LCP, bundle size, and visual regression risk warrant careful QA.

Overview
Homepage and marketing layout shift to a wider content cap (max-w-[1460px], px-20 gutters) applied consistently across (landing)—navbar, blog, integrations, models, pricing, platform/solutions shells, and docs in CLAUDE.md.

Hero is rebuilt as a single stacked column: larger headline, optional HeroStat beside the CTA row, Request a demo / Sign up chip links (replacing the email capture bar), centered TrustedBy row layout, and a full-width media frame (backdrop + platform screenshot) with HeroPlatformLoop—a client island that replays Mothership chat, slides in a workflow pane, builds blocks, and exposes sidebar hover hotspots. The old right-panel HeroVisual is removed from the hero.

A new ProductDemo section sits under the hero and hosts the former HeroVisual loop in a feature-card-style outlined band, with scroll-drawn LoaderMarks.

Features moves from masked FeatureStage + live preview backdrops to FeatureCard rows: Integrate / Context / Monitor use captured product UI in CalloutFrame windows over photo backdrops; Build shows a static support-triage WorkflowShowcase and ThinkingLoader (the goo BuildChatAnimation is added but not wired). CalloutFrame is extracted; formation-graph, logs-table-preview, and the old combined feature-stage module are removed.

landing-preview now wraps the page in LandingShell for prod-like chrome.

Reviewed by Cursor Bugbot for commit 609b0bd. Bugbot is set up for automated code reviews on this repo. Configure here.

fill
priority
sizes='(max-width: 1460px) 83vw, 1080px'
className='object-cover object-top-left'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid hero image anchor class

High Severity

The hero platform screenshot uses object-top-left, which is not a Tailwind v3 utility (this app pins tailwindcss at ^3.4.1). The class is ignored, so object-position falls back to center while HeroPlatformLoop is positioned for a top-left crop—sidebar and live chat chrome can drift out of register.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8e52ff4. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR delivers a comprehensive homepage redesign: a new live-hero with an animated platform UI window (chat streaming, workflow building, draggable blocks), four feature cards with alternating media sides, a promoted product-demo band, refreshed static assets, and minor refinements across the landing. The FloatingTooltip in the shared emcn package gains a configurable offset prop to keep tooltips proportionate over the scaled mini-UI.

  • New HeroPlatformLoop / HeroChatLoop / HeroWorkflowStage trio drives the hero's live layer via a single shared timeline, reusing the existing HeroVisual and WorkflowBlockContent primitives.
  • A new readme-tour-capture/[workspaceId] route serves as a Playwright-driven capture harness that mounts the full real workspace (seeded, no auth); it is labeled "TEMPORARY" and "Not committed" in its JSDoc but is included in this PR targeting staging.
  • proxy.ts middleware exclusion updated to pass /landing/* asset paths through without middleware processing.

Confidence Score: 3/5

Safe to merge after addressing the capture-harness concerns — the landing redesign itself is clean, but the committed "TEMPORARY" route needs an environment gate or removal before this reaches staging.

The landing hero, feature cards, product-demo band, and tooltip offset change are all well-constructed and pose no correctness risk. The two issues that pull the score down both live in the capture-harness route: Zustand store mutations fire during the React render phase (double-fire in Strict Mode), and the route ships to staging with window.__deploy / window.__setView Playwright hooks exposed while mounted and no authentication guard, even though the file's own comment says it is not meant to be committed.

apps/sim/app/landing-preview/readme-tour-capture/[workspaceId]/page.tsx needs the most attention — either add a production environment guard or remove it before merging. apps/sim/app/landing-preview/page.tsx similarly carries a "delete before committing" note and should be reviewed for inclusion.

Important Files Changed

Filename Overview
apps/sim/app/landing-preview/readme-tour-capture/[workspaceId]/page.tsx New 654-line capture harness that mounts the full workspace UI with seeded data; uses useState initializer to trigger Zustand store mutations during render (an anti-pattern that double-fires in Strict Mode) and exposes window.__setCamera/View/deploy globals while mounted. Labeled "TEMPORARY" and "Not committed" but committed here.
apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-platform-loop.tsx New loop orchestrator — clean timer-based animation with correct cancelled flag guard for recursive cycle, proper ResizeObserver teardown, and prefers-reduced-motion handling.
apps/sim/app/(landing)/components/hero/components/hero-platform-loop/hero-workflow-stage.tsx Draggable workflow canvas with stroke-draw edges; byId and builtIds collections rebuilt from scratch on every render (including every drag frame), against the sim-components rule to precompute Maps via useMemo.
apps/sim/app/(landing)/components/hero/components/hero-chat-loop/hero-chat-loop.tsx Word-streaming chat replay — elapsed-time based interval correctly handles throttled tabs; prefers-reduced-motion guard present; cleanup on effect re-run is correct.
apps/sim/app/(landing)/components/hero/components/hero-stat/hero-stat.tsx Staggered count-up stat with all timers and rAF correctly cleaned up on unmount; prefers-reduced-motion respected.
apps/sim/app/(landing)/components/features/components/feature-card/feature-card.tsx New Cursor-style feature card; CSS order logic for mediaSide alternation is correct across breakpoints.
packages/emcn/src/components/tooltip/tooltip.tsx Adds configurable offset prop to FloatingTooltip and Tooltip.Content, defaulting to the existing TOOLTIP_OFFSET constant — backward-compatible change.
apps/sim/next.config.ts Adds Turbopack root path, qualities whitelist for next/image, disables CSS optimization in dev, and disables Turbopack FS cache; all are reasonable build config adjustments.
apps/sim/proxy.ts Adds landing/ to the middleware exclusion pattern so new static landing assets are served directly without passing through the proxy middleware.
apps/sim/app/landing-preview/page.tsx Still carries "delete before committing" in its JSDoc but remains in this PR; wraps Landing in LandingShell — correct otherwise.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Browser
    participant Hero as Hero (RSC)
    participant PlatformLoop as HeroPlatformLoop (client)
    participant ChatLoop as HeroChatLoop
    participant WorkflowStage as HeroWorkflowStage

    Browser->>Hero: Page load
    Hero->>PlatformLoop: Mount live layer over screenshot
    PlatformLoop->>PlatformLoop: ResizeObserver → compute scale
    PlatformLoop->>PlatformLoop: runCycle() starts timer chain
    Note over PlatformLoop: t=500ms
    PlatformLoop->>ChatLoop: "phase=user (user bubble appears)"
    Note over PlatformLoop: t=1400ms
    PlatformLoop->>ChatLoop: "phase=thinking (goo loader)"
    Note over PlatformLoop: t=1900ms
    PlatformLoop->>WorkflowStage: "stageOpen=true (pane slides in)"
    Note over PlatformLoop: t=2400-5500ms
    PlatformLoop->>WorkflowStage: builtCount 1 to 5 (blocks pop in, edges draw)
    Note over PlatformLoop: t=6400ms
    PlatformLoop->>ChatLoop: "phase=reply (word-by-word stream)"
    Note over PlatformLoop: t=12240ms
    PlatformLoop->>PlatformLoop: "fading=true, loop resets"
Loading
%%{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 Browser
    participant Hero as Hero (RSC)
    participant PlatformLoop as HeroPlatformLoop (client)
    participant ChatLoop as HeroChatLoop
    participant WorkflowStage as HeroWorkflowStage

    Browser->>Hero: Page load
    Hero->>PlatformLoop: Mount live layer over screenshot
    PlatformLoop->>PlatformLoop: ResizeObserver → compute scale
    PlatformLoop->>PlatformLoop: runCycle() starts timer chain
    Note over PlatformLoop: t=500ms
    PlatformLoop->>ChatLoop: "phase=user (user bubble appears)"
    Note over PlatformLoop: t=1400ms
    PlatformLoop->>ChatLoop: "phase=thinking (goo loader)"
    Note over PlatformLoop: t=1900ms
    PlatformLoop->>WorkflowStage: "stageOpen=true (pane slides in)"
    Note over PlatformLoop: t=2400-5500ms
    PlatformLoop->>WorkflowStage: builtCount 1 to 5 (blocks pop in, edges draw)
    Note over PlatformLoop: t=6400ms
    PlatformLoop->>ChatLoop: "phase=reply (word-by-word stream)"
    Note over PlatformLoop: t=12240ms
    PlatformLoop->>PlatformLoop: "fading=true, loop resets"
Loading

Comments Outside Diff (1)

  1. apps/sim/app/landing-preview/readme-tour-capture/[workspaceId]/page.tsx, line 1087-1090 (link)

    P1 Side effects inside useState initializer

    useState(() => { seed(queryClient) }) calls useWorkflowStore.getState().setCurrentWorkflowId, replaceWorkflowState, and useWorkflowRegistry.setState during the React render phase. React docs require lazy initializers to be pure. In Strict Mode (the default in development) the initializer fires twice, so these store mutations run twice per mount. The idiomatic fix for "run once, synchronously, before children render" is a useRef guard:

    const seeded = useRef(false)
    if (!seeded.current) {
      seeded.current = true
      seed(queryClient)
    }

Reviews (1): Last reviewed commit: "improvement(landing): homepage redesign ..." | Re-trigger Greptile

Comment on lines +616 to +624
<SandboxWorkspacePermissionsProvider>
<WorkspaceChrome>
{view === 'workflow' ? (
<Workflow workspaceId={WS_ID} workflowId={WF_ID} sandbox />
) : view === 'integrations' ? (
<Suspense fallback={null}>
<Integrations />
</Suspense>
) : view === 'knowledge' ? (

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 "TEMPORARY / Not committed" capture harness shipped to staging

The file's own JSDoc says "TEMPORARY README tour-capture route" and "Not committed." The route at /landing-preview/readme-tour-capture/[workspaceId] mounts the full real workspace chrome (WorkspaceChrome, Workflow, Knowledge, Logs, etc.) in production, seeded with fake data but with no authentication guard. It also exposes window.__setCamera, window.__cardSize, window.__deploy, and window.__setView as global imperative hooks while the page is mounted. These are Playwright automation hooks intended for a local screenshot script, not for a staging or production deployment.

If this route is intentionally included in staging for the capture script to run remotely, please add an environment guard (e.g. if (process.env.NODE_ENV === 'production') notFound()) and note that in the PR description. Otherwise, the file and apps/sim/app/landing-preview/page.tsx (which also says "delete before committing") should be excluded from this diff.

Comment on lines +125 to +126
const byId = new Map(STAGE_BLOCKS.map((b) => [b.id, b]))
const builtIds = new Set(STAGE_BLOCKS.slice(0, builtCount).map((b) => b.id))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 byId and builtIds rebuilt on every drag frame

Both collections are constructed from scratch on each render. Because positions changes on every pointermove, these execute on every drag frame. byId depends only on the module-constant STAGE_BLOCKS and can be a module-level const; builtIds depends on builtCount and should be useMemo'd. Per the sim-components rule: "Precompute a lookup Map once… never array.find per row."

Suggested change
const byId = new Map(STAGE_BLOCKS.map((b) => [b.id, b]))
const builtIds = new Set(STAGE_BLOCKS.slice(0, builtCount).map((b) => b.id))
const builtIds = useMemo(
() => new Set(STAGE_BLOCKS.slice(0, builtCount).map((b) => b.id)),
[builtCount]
)

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

andresdjasso and others added 2 commits July 7, 2026 16:11
…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>
@andresdjasso andresdjasso force-pushed the improvement/landing-homepage-blog branch from 8e52ff4 to d1d0c2c Compare July 7, 2026 20:12
cancelled = true
timers.forEach(clearTimeout)
}
}, [])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reduced motion preference ignored mid-loop

Medium Severity

HeroPlatformLoop reads prefers-reduced-motion only once on mount. If the visitor enables reduced motion after the timed loop starts, the scheduled timeouts keep firing and the chat/stage animation continues. Sibling code such as BuildChatAnimation listens for change on the same media query and stops motion accordingly.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d1d0c2c. Configure here.

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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 3 total unresolved issues (including 2 from previous reviews).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 609b0bd. Configure here.

<LandingShell>
<Landing />
</LandingShell>
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Preview route left in production

Medium Severity

The /landing-preview page is labeled temporary and meant to be removed, yet it ships in this change with force-dynamic and full LandingShell chrome. On self-hosted installs where / redirects to login, that path still serves the public homepage outside the intended entry flow.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 609b0bd. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants