Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions apps/sim/app/(landing)/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ Follow `.claude/rules/constitution.md` exactly: Sim is "the open-source AI works
│ ├── landing-shell/ # light wrapper + skip link + Navbar(stars) + Footer; wraps every page
│ ├── hero-cta/ # the one email-capture + Sign-up CTA (hero + every platform hero)
│ └── logos/ # the one customer-logo set; layout='grid' (hero) | 'row' (platform)
└── platform-page/ # the reusable platform-page layout (Workflows, Tables, Files, )
├── platform-page.tsx, index.ts, types.ts, constants.ts # PlatformPage + the content contract + spacing
└── components/ # platform-hero, platform-logos-row, platform-card-row (→ card, pill-cta),
# platform-visual-frame, platform-structured-data
└── solutions-page/ # the reusable solutions/platform layout (Workflows, Knowledge, Tables, Files, Logs, solutions/*)
├── solutions-page.tsx, index.ts, types.ts, constants.ts # SolutionsPage + the content contract + spacing
└── components/ # solutions-hero, solutions-logos-row, solutions-card-row (→ card, pill-cta),
# solutions-visual-frame, solutions-structured-data
```

Each section component's TSDoc carries its layout spec - read it before implementing. Section components own their landmark (Navbar → `<header>`, Footer → `<footer>`, the rest → `<section>`); the shared `LandingShell` owns the page frame (light wrapper, skip link, navbar, footer, GitHub stars via `@/lib/github/stars` - fetched at build/revalidate time, never client-fetched), and the page's `<main>` owns the section order and rhythm. Platform routes consume `PlatformPage` with a single content `config` - see `platform-page/CLAUDE`-level TSDoc on `platform-page.tsx`. Sub-components of a section go in `components/<section>/components/`.
Each section component's TSDoc carries its layout spec - read it before implementing. Section components own their landmark (Navbar → `<header>`, Footer → `<footer>`, the rest → `<section>`); the shared `LandingShell` owns the page frame (light wrapper, skip link, navbar, footer, GitHub stars via `@/lib/github/stars` - fetched at build/revalidate time, never client-fetched), and the page's `<main>` owns the section order and rhythm. Platform and solutions routes consume `SolutionsPage` with a single content `config` - see the TSDoc on `solutions-page.tsx`. Sub-components of a section go in `components/<section>/components/`.

Absolute imports only in component code (`@/app/(landing)/components/...`); `index.ts` barrels use relative re-exports (`export { X } from './x'`), matching the workspace convention. Props interfaces for every component. No `utils.ts` until two files share a helper.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ interface HeroWorkflowStageProps {
edges?: ReadonlyArray<readonly [string, string]>
/** Design-space bounding box of the block layout. Defaults with them. */
canvas?: { width: number; height: number }
/**
* Block to dress with the selection ring - graphite (`--text-secondary`)
* rather than the real canvas's blue, per the landing pages' grayscale
* language - the workflows hero uses this for its "being edited" beat.
* Off by default, so existing stages are unchanged.
*/
selectedId?: string
}

/**
Expand All @@ -55,6 +62,7 @@ export function HeroWorkflowStage({
blocks = STAGE_BLOCKS,
edges = STAGE_EDGES,
canvas = STAGE_CANVAS,
selectedId,
}: HeroWorkflowStageProps) {
const containerRef = useRef<HTMLDivElement>(null)
const [scale, setScale] = useState(MAX_STAGE_SCALE)
Expand Down Expand Up @@ -154,6 +162,13 @@ export function HeroWorkflowStage({
style={{ left: block.x, top: block.y, width: BLOCK_WIDTH }}
>
<StageBlockCard block={block} />
<span
aria-hidden
className={cn(
'pointer-events-none absolute inset-0 rounded-[13px] ring-[1.75px] ring-[var(--text-secondary)] transition-opacity duration-300 ease-out',
selectedId === block.id && built ? 'opacity-100' : 'opacity-0'
)}
/>
</div>
)
})}
Expand Down
9 changes: 1 addition & 8 deletions apps/sim/app/(landing)/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,7 @@ export { Lightbox } from './lightbox'
export { LogoShell } from './logo-shell'
export { Mothership } from './mothership/mothership'
export { Navbar } from './navbar'
export type {
PlatformCardConfig,
PlatformCardRowConfig,
PlatformHeroConfig,
PlatformPageConfig,
PlatformPillCta,
} from './platform-page'
export { PlatformPage } from './platform-page'
export { PlatformHeroVisual } from './platform-hero-visual'
export { ProductDemo } from './product-demo'
export { ShareButton } from './share-button'
export { SiteStructuredData } from './site-structured-data'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,12 @@ import { DEMO_HREF, SIGNUP_HREF } from '@/app/(landing)/constants'
* leaf hydrates; the desktop nav stays server-rendered.
*
* The sheet locks body scroll while open and closes on route change intent
* (any link tap) and on `Escape`. Motion is a short token-driven
* transform/opacity that collapses under `prefers-reduced-motion`.
* (any link tap) and on `Escape`. With all three mega-menus expanded the
* sections outgrow a phone viewport, so the sheet caps its height at the
* space under the bar (`100dvh` minus the bar's 62px) and scrolls internally
* (`overscroll-contain` keeps the locked page from rubber-banding behind it).
* Motion is a short token-driven transform/opacity that collapses under
* `prefers-reduced-motion`.
*/

interface MobileNavProps {
Expand All @@ -35,9 +39,9 @@ interface MobileNavProps {
/**
* Standalone top-level routes shown in the sheet alongside the expanded mega-menu
* sections. Pricing is a standalone link on the desktop nav (not a mega-menu), so
* it stays a single row here too. Restoring `PLATFORM_MENU`/`SOLUTIONS_MENU` to
* {@link NAV_MENUS} automatically expands them here as grouped sections too - the
* sheet mirrors the desktop nav's information architecture with no extra edit.
* it stays a single row here too. Every menu in {@link NAV_MENUS} expands here as
* a grouped section automatically - the sheet mirrors the desktop nav's
* information architecture with no extra edit.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicate Enterprise nav entries

Medium Severity

Restoring SOLUTIONS_MENU into NAV_MENUS puts Enterprise in that mega-menu, but the desktop bar and mobile sheet still keep a standalone Enterprise link. Visitors now see the same destination twice in primary navigation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2bd998f. Configure here.

*/
const STANDALONE_LINKS = [
{ label: 'Enterprise', href: '/enterprise' },
Expand Down Expand Up @@ -96,7 +100,7 @@ export function MobileNav({ stars }: MobileNavProps) {

<div
className={cn(
'absolute top-full right-0 left-0 z-50 origin-top border-[var(--border)] border-b transition-[opacity,transform] duration-200 motion-reduce:transition-none',
'absolute top-full right-0 left-0 z-50 max-h-[calc(100dvh-62px)] origin-top overflow-y-auto overscroll-contain border-[var(--border)] border-b transition-[opacity,transform] duration-200 motion-reduce:transition-none',
NAVBAR_GLASS_SURFACE,
open
? 'pointer-events-auto translate-y-0 opacity-100'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ import type { NavMenu } from '@/app/(landing)/components/navbar/components/nav-m
export const PLATFORM_MENU: NavMenu = {
label: 'Platform',
items: [
{
title: 'Mothership',
description: 'Build and command agents in natural language',
href: '/',
},
{
title: 'Workflows',
description: 'Design agent logic visually',
Expand All @@ -32,6 +27,11 @@ export const PLATFORM_MENU: NavMenu = {
description: 'One file store for team and agents',
href: '/files',
},
{
title: 'Scheduled Tasks',
description: 'Run agents on a cadence',
href: '/scheduled-tasks',
},
{
title: 'Logs',
description: 'Trace every agent decision',
Expand Down Expand Up @@ -121,13 +121,9 @@ export const SOLUTIONS_MENU: NavMenu = {
}

/**
* Navbar mega-menus that are currently rendered, in trigger order - shared by
* desktop and mobile nav (the desktop bar maps this list; mobile nav derives
* its visible sections from these labels).
*
* `PLATFORM_MENU` and `SOLUTIONS_MENU` are intentionally omitted for now to hide
* those sections from navigation while their pages stay live and reachable by
* direct URL. The menu definitions above are kept intact - to restore a section,
* add its constant back to this list.
* Navbar mega-menus in trigger order - shared by desktop and mobile nav (the
* desktop bar maps this list; mobile nav derives its visible sections from
* these labels). Platform leads with the product modules, Solutions follows
* with the per-team pages, and Resources closes with learning surfaces.
*/
export const NAV_MENUS = [RESOURCES_MENU] as const
export const NAV_MENUS = [PLATFORM_MENU, SOLUTIONS_MENU, RESOURCES_MENU] as const

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicate Enterprise nav entry

Medium Severity

Restoring SOLUTIONS_MENU into NAV_MENUS surfaces Enterprise under Solutions, but the desktop bar and mobile sheet still keep a standalone Enterprise link. Visitors now see two separate entries to the same /enterprise route in both desktop and mobile navigation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 73724ca. Configure here.

Comment thread
cursor[bot] marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ import type { NavMenu } from '@/app/(landing)/components/navbar/components/nav-m
* The panel chrome replicates the `ChipModal` framed-card look exactly: an outer
* `--surface-4` ring (`p-[3px]`, overlay shadow) wrapping an inner `--bg`
* surface, with the item grid padded inside.
*
* The grid renders three visual columns on six tracks (each tile spans two),
* which keeps six-item menus pixel-identical to a plain three-column grid while
* letting a five-item menu center its two-tile last row - the second-to-last
* tile starts on track two, so the short row sits symmetrically instead of
* leaving a hole in the corner.
*/

interface NavMenuChipProps {
Expand Down Expand Up @@ -74,7 +80,14 @@ export function NavMenuChip({ menu }: NavMenuChipProps) {
<div className={cn(PANEL_BASE, !closed && PANEL_REVEAL)}>
<div className='w-[840px] rounded-xl border border-[var(--border-muted)] bg-[var(--surface-4)] p-[3px] shadow-[var(--shadow-overlay)]'>
<div className='rounded-lg border border-[var(--border-1)] bg-[var(--bg)] p-2'>
<div className='grid grid-cols-3 gap-1' role='group' aria-label={label}>
<div
className={cn(
'grid grid-cols-6 gap-1 [&>*]:col-span-2',
items.length % 3 === 2 && '[&>*:nth-last-child(2)]:col-start-2'
)}
role='group'
aria-label={label}
>
{items.map((item) => (
<NavMenuItem key={item.title} item={item} onSelect={handleSelect} />
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { PlatformHeroVisual } from '@/app/(landing)/components/platform-hero-visual/platform-hero-visual'
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { ReactNode } from 'react'
import Image from 'next/image'

interface PlatformHeroVisualProps {
/** The live platform interior - a platform loop or editor loop island. */
children: ReactNode
}

/**
* The enterprise hero's visual composition, shared: the architectural backdrop
* (`enterprise-hero-background.webp`) with the white demo window framed in
* front of it, ready to hold a live platform interior (a chat platform loop or
* the workflows editor loop). Extracted so the solutions and workflows heroes
* reuse the exact backdrop, window geometry (`aspect-[1080/620]` at 83.08%
* width), and shadow treatment the enterprise page established - the
* enterprise page keeps its own inline copy, byte-identical.
*
* Renders inside a hero visual slot (the `variant='home'` media frame or the
* standard {@link SolutionsVisualFrame}); the outer `relative` wrapper anchors
* the `fill` image in frames that don't position themselves.
*/
export function PlatformHeroVisual({ children }: PlatformHeroVisualProps) {
return (
<div className='relative h-full w-full'>
<Image
fill
priority
fetchPriority='high'
alt=''
className='object-cover object-center'
sizes='(max-width: 1024px) 100vw, 1300px'
src='/landing/enterprise-hero-background.webp'
/>
<div className='-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2 flex aspect-[1080/620] w-[83.08%] flex-col overflow-hidden rounded-[10px] bg-[var(--surface-1)] shadow-[0_0_0_1px_rgba(0,0,0,0.08),0_2px_6px_0_rgba(0,0,0,0.05),0_4px_42px_0_rgba(0,0,0,0.06)]'>
<div className='relative flex-1'>{children}</div>
</div>
</div>
)
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading