diff --git a/apps/sim/app/(landing)/components/footer/footer.tsx b/apps/sim/app/(landing)/components/footer/footer.tsx
index 09b07babd54..ebf30480172 100644
--- a/apps/sim/app/(landing)/components/footer/footer.tsx
+++ b/apps/sim/app/(landing)/components/footer/footer.tsx
@@ -1,4 +1,5 @@
import Link from 'next/link'
+import { ALL_COMPETITORS } from '@/app/(landing)/comparisons/utils'
import { SimWordmark } from '@/app/(landing)/components/navbar/components/sim-wordmark'
import { MODEL_PROVIDERS_WITH_CATALOGS } from '@/app/(landing)/models/utils'
@@ -41,7 +42,7 @@ const PRODUCT_LINKS: FooterItem[] = [
const RESOURCES_LINKS: FooterItem[] = [
{ label: 'Blog', href: '/blog' },
{ label: 'Docs', href: 'https://docs.sim.ai', external: true },
- { label: 'Compare', href: '/comparisons' },
+ { label: 'Library', href: '/library' },
{ label: 'Careers', href: '/careers' },
{ label: 'Changelog', href: '/changelog' },
{ label: 'Contact', href: '/contact' },
@@ -56,17 +57,13 @@ const MODEL_LINKS: FooterItem[] = [
})),
]
-const BLOCK_LINKS: FooterItem[] = [
- { label: 'Agent', href: 'https://docs.sim.ai/workflows/blocks/agent', external: true },
- { label: 'Router', href: 'https://docs.sim.ai/workflows/blocks/router', external: true },
- { label: 'Function', href: 'https://docs.sim.ai/workflows/blocks/function', external: true },
- { label: 'Condition', href: 'https://docs.sim.ai/workflows/blocks/condition', external: true },
- { label: 'API Block', href: 'https://docs.sim.ai/workflows/blocks/api', external: true },
- { label: 'Workflow', href: 'https://docs.sim.ai/workflows/blocks/workflow', external: true },
- { label: 'Parallel', href: 'https://docs.sim.ai/workflows/blocks/parallel', external: true },
- { label: 'Guardrails', href: 'https://docs.sim.ai/workflows/blocks/guardrails', external: true },
- { label: 'Evaluator', href: 'https://docs.sim.ai/workflows/blocks/evaluator', external: true },
- { label: 'Loop', href: 'https://docs.sim.ai/workflows/blocks/loop', external: true },
+/** Top comparison pages, sourced from the competitor catalog so labels/hrefs never drift. */
+const COMPARE_LINKS: FooterItem[] = [
+ { label: 'All Comparisons', href: '/comparisons' },
+ ...ALL_COMPETITORS.slice(0, 9).map((competitor) => ({
+ label: competitor.name,
+ href: `/comparisons/${competitor.id}`,
+ })),
]
const INTEGRATION_LINKS: FooterItem[] = [
@@ -153,7 +150,7 @@ export function Footer() {
-
+
diff --git a/apps/sim/app/(landing)/components/navbar/components/mobile-nav/mobile-nav.tsx b/apps/sim/app/(landing)/components/navbar/components/mobile-nav/mobile-nav.tsx
index f0963c229d4..4790edb28d1 100644
--- a/apps/sim/app/(landing)/components/navbar/components/mobile-nav/mobile-nav.tsx
+++ b/apps/sim/app/(landing)/components/navbar/components/mobile-nav/mobile-nav.tsx
@@ -43,10 +43,7 @@ interface MobileNavProps {
* a grouped section automatically - the sheet mirrors the desktop nav's
* information architecture with no extra edit.
*/
-const STANDALONE_LINKS = [
- { label: 'Enterprise', href: '/enterprise' },
- { label: 'Pricing', href: '/pricing' },
-] as const
+const STANDALONE_LINKS = [{ label: 'Pricing', href: '/pricing' }] as const
/** Shared row chrome for every tappable text link in the sheet. */
const SHEET_ROW =
diff --git a/apps/sim/app/(landing)/components/navbar/components/nav-menu-chip/constants.ts b/apps/sim/app/(landing)/components/navbar/components/nav-menu-chip/constants.ts
index 9a74b6142c4..b598d046e72 100644
--- a/apps/sim/app/(landing)/components/navbar/components/nav-menu-chip/constants.ts
+++ b/apps/sim/app/(landing)/components/navbar/components/nav-menu-chip/constants.ts
@@ -41,8 +41,8 @@ export const PLATFORM_MENU: NavMenu = {
}
/**
- * The Resources menu - learning and reference surfaces. Six items in a
- * three-column grid. Docs is the one off-site link.
+ * The Resources menu - learning and reference surfaces plus the Enterprise
+ * page. Six items in a three-column grid. Docs is the one off-site link.
*/
export const RESOURCES_MENU: NavMenu = {
label: 'Resources',
@@ -59,9 +59,9 @@ export const RESOURCES_MENU: NavMenu = {
href: '/blog',
},
{
- title: 'Library',
- description: 'Comparisons, how-tos, and roundups',
- href: '/library',
+ title: 'Enterprise',
+ description: 'Govern AI agents at enterprise scale',
+ href: '/enterprise',
},
{
title: 'Changelog',
@@ -82,15 +82,16 @@ export const RESOURCES_MENU: NavMenu = {
}
/**
- * The Solutions menu - agent use cases by team. Six items in a three-column grid.
+ * The Solutions menu - agent use cases by team, Sales first. Six items in a
+ * three-column grid.
*/
export const SOLUTIONS_MENU: NavMenu = {
label: 'Solutions',
items: [
{
- title: 'Enterprise',
- description: 'Govern AI agents at enterprise scale',
- href: '/enterprise',
+ title: 'Sales',
+ description: 'Automate outreach and CRM upkeep',
+ href: '/solutions/sales',
},
{
title: 'Engineering',
diff --git a/apps/sim/app/(landing)/components/navbar/navbar.tsx b/apps/sim/app/(landing)/components/navbar/navbar.tsx
index ee7cbb30444..2cf7458cac6 100644
--- a/apps/sim/app/(landing)/components/navbar/navbar.tsx
+++ b/apps/sim/app/(landing)/components/navbar/navbar.tsx
@@ -34,6 +34,7 @@ import { DEMO_HREF, SIGNUP_HREF } from '@/app/(landing)/constants'
* chip-height slot, chip-text color) → the {@link NAV_MENUS} mega-menus
* (pure-CSS hover/focus dropdowns) → Pricing → GitHub stars. Right side: Log in
* (default chip), Contact sales (outline chip), Sign up (filled chip).
+ * Enterprise lives inside the Resources mega-menu, not as a standalone chip.
*/
interface NavbarProps {
@@ -75,9 +76,6 @@ export function Navbar({ stars, logoOnly = false }: NavbarProps) {
{NAV_MENUS.map((menu) => (
))}
-
- Enterprise
-
Pricing
diff --git a/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/index.ts b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/index.ts
new file mode 100644
index 00000000000..35e43aa2af3
--- /dev/null
+++ b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/index.ts
@@ -0,0 +1 @@
+export { ScheduledTasksCalendarLoop } from './scheduled-tasks-calendar-loop'
diff --git a/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.module.css b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.module.css
new file mode 100644
index 00000000000..ea6ba04bb0a
--- /dev/null
+++ b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.module.css
@@ -0,0 +1,28 @@
+/**
+ * The ScheduledTasksCalendarLoop's motion: a newly scheduled task pill stamps
+ * in once when the parent clock mounts it on its calendar day. A one-shot
+ * mount animation - the loop's restart unmounts and remounts the pills, so a
+ * new cycle replays them naturally. Under prefers-reduced-motion the parent
+ * renders the finished frame and this never plays.
+ */
+
+.pillIn {
+ animation: scheduled-tasks-pill-in 0.35s cubic-bezier(0.22, 1, 0.36, 1) backwards;
+}
+
+@keyframes scheduled-tasks-pill-in {
+ from {
+ opacity: 0;
+ transform: translateY(-4px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+@media (prefers-reduced-motion: reduce) {
+ .pillIn {
+ animation: none;
+ }
+}
diff --git a/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.tsx b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.tsx
new file mode 100644
index 00000000000..73824540eae
--- /dev/null
+++ b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.tsx
@@ -0,0 +1,300 @@
+'use client'
+
+import { useState } from 'react'
+import { Chip, chipContentGap, chipPrimaryFillTokens, cn } from '@sim/emcn'
+import { Calendar, Plus } from '@sim/emcn/icons'
+import { ChevronLeft, ChevronRight } from 'lucide-react'
+import { HeroLoopShell } from '@/app/(landing)/components/shared/hero-loop-shell'
+import { RESET_FADE_MS } from '@/app/(landing)/hooks/use-design-scale'
+import { useMotionSafeCycle } from '@/app/(landing)/hooks/use-motion-safe-cycle'
+import styles from '@/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop/scheduled-tasks-calendar-loop.module.css'
+
+/** Sidebar content for the scheduled-tasks hero - a recurring-ops workspace. */
+const SIDEBAR_CHATS = [
+ 'Morning digest setup',
+ 'Move sync to nightly',
+ 'Weekly KPI report',
+ 'Retry failed runs',
+] as const
+
+/** Deployed workflows in the sidebar - five fill the design height. */
+const SIDEBAR_WORKFLOWS = [
+ 'Morning digest',
+ 'Nightly data sync',
+ 'Weekly KPI report',
+ 'Invoice sweep',
+ 'Churn-risk alerts',
+] as const
+
+/** Weekday header labels, Sunday-start, matching the real month grid. */
+const WEEKDAY_LABELS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] as const
+
+/** Month the fixed calendar shows - June 2026 opens on a Monday and fills five Sunday-start weeks. */
+const MONTH_LABEL = 'June 2026'
+/** Day-of-month carrying the today ring, a mid-month Wednesday. */
+const TODAY = 10
+/** Days in June - the grid's in-month cells span indexes 1..30. */
+const DAYS_IN_MONTH = 30
+/** Total cells in the five-week Sunday-start grid. */
+const CELL_COUNT = 35
+
+interface CalendarPill {
+ /** Occurrence start time, preformatted like the real event chip's `h:mm a`. */
+ time: string
+ /** Scheduled task title. */
+ title: string
+ /** Paused schedules render dimmed - the one status the real pill signals. */
+ paused?: boolean
+ /**
+ * Position of this pill in the animated stamp-in series (the Weekly KPI
+ * report being scheduled across the month's Mondays); unset pills are the
+ * settled base calendar.
+ */
+ stampIndex?: number
+}
+
+interface CalendarCell {
+ /** Day-of-month number the cell shows. */
+ day: number
+ /** In-month days get body-colored numbers; leading/trailing days go muted. */
+ inMonth: boolean
+ /** Today's number gets the real grid's 26px primary-filled square. */
+ isToday: boolean
+ /** Task occurrences on this day, in start-time order. */
+ pills: CalendarPill[]
+}
+
+/** Mondays in the grid (cell indexes), in stamp order for the animated series. */
+const MONDAY_CELLS: readonly number[] = [1, 8, 15, 22, 29]
+
+/**
+ * Derives one day's task pills from the workspace's recurring schedules:
+ * the Morning digest on weekdays at 9:00 AM, the paused Churn-risk alerts on
+ * Thursdays, the Nightly data sync every night, a monthly Invoice sweep on
+ * the 30th, and - as the animated series - the Weekly KPI report landing on
+ * each Monday as the schedule is created.
+ */
+function pillsForCell(index: number): CalendarPill[] {
+ const weekday = index % 7
+ const pills: CalendarPill[] = []
+ const mondayOrder = MONDAY_CELLS.indexOf(index)
+ if (mondayOrder !== -1) {
+ pills.push({ time: '8:00 AM', title: 'Weekly KPI report', stampIndex: mondayOrder })
+ }
+ if (weekday >= 1 && weekday <= 5) {
+ pills.push({ time: '9:00 AM', title: 'Morning digest' })
+ }
+ if (index === DAYS_IN_MONTH) {
+ pills.push({ time: '3:00 PM', title: 'Invoice sweep' })
+ }
+ if (weekday === 4) {
+ pills.push({ time: '4:00 PM', title: 'Churn-risk alerts', paused: true })
+ }
+ pills.push({ time: '11:00 PM', title: 'Nightly data sync' })
+ return pills
+}
+
+/**
+ * The fixed June 2026 grid: May 31 leads the first week, June fills the
+ * middle, and July 1-4 close the fifth week - every cell's pills derived
+ * from the recurring schedules above.
+ */
+const CALENDAR_CELLS: readonly CalendarCell[] = Array.from({ length: CELL_COUNT }, (_, index) => {
+ const inMonth = index >= 1 && index <= DAYS_IN_MONTH
+ const day = index === 0 ? 31 : inMonth ? index : index - DAYS_IN_MONTH
+ return {
+ day,
+ inMonth,
+ isToday: index === TODAY,
+ pills: pillsForCell(index),
+ }
+})
+
+/** Total pills the animated Weekly KPI series stamps onto the month's Mondays. */
+const TOTAL_STAMPED_PILLS = MONDAY_CELLS.length
+
+/** The settled calendar holds this long before the first KPI pill lands. */
+const IDLE_HOLD_MS = 900
+/** Stamped pill N lands at IDLE_HOLD_MS + N * PILL_STEP_MS. */
+const PILL_STEP_MS = 620
+/** The fully scheduled month holds this long before the fade. */
+const SCHEDULED_HOLD_MS = 5200
+
+interface CalendarPanePillProps {
+ pill: CalendarPill
+ /** Stamped pills replay the mount animation each cycle. */
+ animate: boolean
+}
+
+/**
+ * One task pill in a day cell - the real calendar event chip's exact
+ * chrome (primary fill, start time + title, paused schedules dimmed) rendered
+ * as a plain `
` since the whole frame is `aria-hidden` decoration.
+ */
+function CalendarPanePill({ pill, animate }: CalendarPanePillProps) {
+ return (
+
+ {pill.time}
+ {pill.title}
+
+ )
+}
+
+interface ScheduledTasksCalendarPaneProps {
+ /** How many Weekly KPI pills the stamp-in series has landed (0..5). */
+ stampedCount: number
+}
+
+/**
+ * The static Scheduled Tasks page in the real workspace's exact vocabulary -
+ * the resource header (Calendar icon + title + primary "New scheduled task"
+ * chip), the calendar toolbar (Today jump, period label, prev/next chevrons,
+ * scope chip), the sticky weekday header, and the five-week month grid of day
+ * cells with the today square and stacked task pills - rendered from the
+ * parent clock's `stampedCount` beat.
+ */
+function ScheduledTasksCalendarPane({ stampedCount }: ScheduledTasksCalendarPaneProps) {
+ return (
+
+
+
+
+ Scheduled Tasks
+
+
+ New scheduled task
+
+
+
+
+
+ Today
+ {MONTH_LABEL}
+
+
+
+
+ Month
+
+
+
+
+ {WEEKDAY_LABELS.map((label, index) => (
+
+ {label}
+
+ ))}
+
+
+
+ {CALENDAR_CELLS.map((cell, index) => (
+
+
+ {cell.day}
+
+
+ {cell.pills.map((pill) =>
+ pill.stampIndex !== undefined && pill.stampIndex >= stampedCount ? null : (
+
+ )
+ )}
+
+
+ ))}
+
+
+ )
+}
+
+/**
+ * The scheduled-tasks hero's calendar loop - the workspace's real Scheduled
+ * Tasks surface as the workspace pane. Same architecture as the sibling hero
+ * loops (the {@link HeroLoopShell}'s fixed 1280x735 design-space layer scaled
+ * to the window, a parent-owned clock driving a presentational pane,
+ * reduced-motion showing the finished frame) and the same live sidebar with
+ * its Scheduled tasks nav row highlighted, but the pane is the month calendar
+ * itself: the settled recurring schedules hold, then a new Weekly KPI report
+ * schedule lands pill by pill across the month's Mondays, the fully
+ * scheduled month holds, and the scene fades before the cycle restarts.
+ *
+ * Everything is `pointer-events-none` decorative, matching the hero's
+ * `aria-hidden` frame. Under `prefers-reduced-motion` the loop never starts:
+ * the fully scheduled calendar renders statically.
+ */
+export function ScheduledTasksCalendarLoop() {
+ const [stampedCount, setStampedCount] = useState(0)
+ const [fading, setFading] = useState(false)
+ const [cycleId, setCycleId] = useState(0)
+
+ useMotionSafeCycle({
+ scheduleCycle: () => {
+ setFading(false)
+ setStampedCount(0)
+ setCycleId((c) => c + 1)
+ const totalMs = IDLE_HOLD_MS + (TOTAL_STAMPED_PILLS - 1) * PILL_STEP_MS + SCHEDULED_HOLD_MS
+ return {
+ timers: [
+ ...Array.from({ length: TOTAL_STAMPED_PILLS }, (_, i) =>
+ setTimeout(() => setStampedCount(i + 1), IDLE_HOLD_MS + i * PILL_STEP_MS)
+ ),
+ setTimeout(() => setFading(true), totalMs - RESET_FADE_MS),
+ ],
+ totalMs,
+ }
+ },
+ showFinished: () => {
+ setFading(false)
+ setStampedCount(TOTAL_STAMPED_PILLS)
+ },
+ })
+
+ return (
+
+
+
+ )
+}
diff --git a/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-hero-loop.tsx b/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-hero-loop.tsx
deleted file mode 100644
index ef0ccaaf3c7..00000000000
--- a/apps/sim/app/(landing)/scheduled-tasks/components/scheduled-tasks-hero-loop.tsx
+++ /dev/null
@@ -1,117 +0,0 @@
-'use client'
-
-import { AgentIcon, GmailIcon, GoogleSheetsIcon, ScheduleIcon, SlackIcon } from '@/components/icons'
-import { EditorLoop, type EditorLoopContent } from '@/app/(landing)/components/shared/editor-loop'
-
-/**
- * The scheduled-tasks hero's content for the shared {@link EditorLoop}: a
- * recurring-ops workspace sidebar and the complete scheduled digest workflow -
- * a schedule trigger holding the cadence, the digest agent, and a three-way
- * fan-out to Slack, Gmail, and Sheets. The schedule trigger is the block the
- * "editing" beat selects, since the cadence is this page's story. Colors
- * follow the stage convention - grey ramp for platform blocks, brand tiles
- * only for real third-party marks (multicolor Gmail/Sheets glyphs sit on
- * white tiles with a hairline, the Jira treatment). Blocks are ordered by
- * build sequence; an edge draws once both endpoints are on canvas.
- */
-const SCHEDULED_TASKS_EDITOR_CONTENT: EditorLoopContent = {
- activeNav: 'Scheduled tasks',
- sidebarChats: [
- 'Morning digest setup',
- 'Move sync to nightly',
- 'Weekly KPI report',
- 'Retry failed runs',
- ],
- sidebarWorkflows: [
- 'Morning digest',
- 'Nightly data sync',
- 'Weekly KPI report',
- 'Invoice sweep',
- 'Churn-risk alerts',
- ],
- blocks: [
- {
- id: 'schedule',
- name: 'Schedule',
- icon: ScheduleIcon,
- bgColor: 'var(--text-muted)',
- isTrigger: true,
- rows: [
- { title: 'Cadence', value: 'Weekdays' },
- { title: 'Time', value: '9:00 AM PT' },
- ],
- x: 555,
- y: 20,
- },
- {
- id: 'agent',
- name: 'Digest agent',
- icon: AgentIcon,
- bgColor: 'var(--text-primary)',
- rows: [
- { title: 'Messages', value: '-' },
- { title: 'Model', value: '-' },
- ],
- x: 555,
- y: 280,
- },
- {
- id: 'slack',
- name: 'Post to Slack',
- icon: SlackIcon,
- bgColor: '#611F69',
- isTerminal: true,
- rows: [
- { title: 'Channel', value: '-' },
- { title: 'Message', value: '-' },
- ],
- x: 100,
- y: 560,
- },
- {
- id: 'gmail',
- name: 'Send by email',
- icon: GmailIcon,
- bgColor: '#FFFFFF',
- tileBorder: true,
- isTerminal: true,
- rows: [
- { title: 'To', value: '-' },
- { title: 'Subject', value: '-' },
- ],
- x: 555,
- y: 560,
- },
- {
- id: 'sheets',
- name: 'Append to Sheets',
- icon: GoogleSheetsIcon,
- bgColor: '#FFFFFF',
- tileBorder: true,
- isTerminal: true,
- rows: [
- { title: 'Spreadsheet', value: '-' },
- { title: 'Range', value: '-' },
- ],
- x: 1010,
- y: 560,
- },
- ],
- edges: [
- ['schedule', 'agent'],
- ['agent', 'slack'],
- ['agent', 'gmail'],
- ['agent', 'sheets'],
- ],
- canvas: { width: 1360, height: 780 },
- selectedBlockId: 'schedule',
-}
-
-/**
- * The scheduled-tasks hero's editor loop - the shared {@link EditorLoop}
- * replaying the morning-digest workflow with the schedule trigger as the
- * "being edited" beat, the cadence being this page's story.
- */
-export function ScheduledTasksHeroLoop() {
- return
-}
diff --git a/apps/sim/app/(landing)/scheduled-tasks/scheduled-tasks.tsx b/apps/sim/app/(landing)/scheduled-tasks/scheduled-tasks.tsx
index 6a862acccc3..8a8113f25f3 100644
--- a/apps/sim/app/(landing)/scheduled-tasks/scheduled-tasks.tsx
+++ b/apps/sim/app/(landing)/scheduled-tasks/scheduled-tasks.tsx
@@ -10,7 +10,7 @@ import {
OperationsTeamsGraphic,
RunMonitoringGraphic,
} from '@/app/(landing)/enterprise/components/feature-graphics'
-import { ScheduledTasksHeroLoop } from '@/app/(landing)/scheduled-tasks/components/scheduled-tasks-hero-loop'
+import { ScheduledTasksCalendarLoop } from '@/app/(landing)/scheduled-tasks/components/scheduled-tasks-calendar-loop'
import { DocumentDraftGraphic } from '@/app/(landing)/solutions/components/feature-graphics'
/**
@@ -21,7 +21,9 @@ import { DocumentDraftGraphic } from '@/app/(landing)/solutions/components/featu
* schedule triggers (from every-15-minutes intervals through daily, weekly,
* and monthly cadences to custom cron, timezone-aware), and the workspace's
* Scheduled Tasks calendar shows every upcoming and finished run with
- * pause/resume and full run history. Every visual slot reuses a
+ * pause/resume and full run history. The hero replays that calendar itself -
+ * the month grid filling with recurring task pills as a new schedule lands
+ * on its cadence. Every card visual slot reuses a
* parametrized enterprise feature graphic retold for recurring runs - the
* policy checklist as a schedule card, the routing fan as the delivery
* fan-out, the drafted document as the digest that arrives on time, the
@@ -42,7 +44,7 @@ const SCHEDULED_TASKS_CONFIG: SolutionsPageConfig = {
'Scheduled Tasks is the scheduler in Sim, the open-source AI workspace where teams build, deploy, and manage AI agents. Put any workflow on a cadence, from 15-minute intervals to daily, weekly, and monthly runs or custom cron, timezone-aware, then watch every scheduled run land on the workspace calendar with full run history.',
visual: (
-
+
),
},
diff --git a/apps/sim/app/(landing)/solutions/sales/components/sales-hero-loop.tsx b/apps/sim/app/(landing)/solutions/sales/components/sales-hero-loop.tsx
new file mode 100644
index 00000000000..27355ac0b4a
--- /dev/null
+++ b/apps/sim/app/(landing)/solutions/sales/components/sales-hero-loop.tsx
@@ -0,0 +1,125 @@
+'use client'
+
+import {
+ AgentIcon,
+ ConditionalIcon,
+ SalesforceIcon,
+ SlackIcon,
+ StartIcon,
+} from '@/components/icons'
+import { EnterprisePlatformLoop } from '@/app/(landing)/enterprise/components/enterprise-platform-loop'
+import type { EnterpriseLoopContent } from '@/app/(landing)/enterprise/components/enterprise-platform-loop/stage-data'
+
+/**
+ * Sales content for the shared platform loop - an inbound-lead agent: the
+ * prompt asks for lead research, fit scoring, and Salesforce record creation
+ * with a Slack alert to the owner, the sidebar reads like the sales team's
+ * Brightwave workspace, and the staged workflow builds the routing flow on
+ * the enterprise stage geometry. The Salesforce mark is a colored brand
+ * mark, so its tile follows the Jira convention - the real mark on a
+ * hairlined white tile.
+ */
+const SALES_LOOP_CONTENT: EnterpriseLoopContent = {
+ workspaceName: 'Brightwave Sales',
+ greeting: 'What should we get done, Marcus?',
+ placeholder: 'Ask Sim to automate a process.',
+ prompt:
+ 'When a new lead comes in, research the company, score the fit, create the record in Salesforce, and alert the account owner in Slack.',
+ reply:
+ "On it. I'll research every new lead, score the fit against your best customers, create the Salesforce record, and alert the owner in Slack.",
+ sidebarChats: [
+ 'Inbound lead backlog',
+ 'Acme Co renewal prep',
+ 'Q3 forecast review',
+ 'Stale opportunity cleanup',
+ ],
+ sidebarWorkflows: [
+ 'Lead research',
+ 'Inbound routing',
+ 'CRM hygiene',
+ 'Meeting prep briefs',
+ 'Weekly pipeline digest',
+ ],
+ suggestedActions: [
+ 'Research this week\u2019s inbound leads',
+ 'Update stale opportunities',
+ 'Draft follow-ups from yesterday\u2019s calls',
+ 'Summarize the Q3 pipeline',
+ ],
+ stageBlocks: [
+ {
+ id: 'start',
+ name: 'Start',
+ icon: StartIcon,
+ bgColor: 'var(--text-muted)',
+ isTrigger: true,
+ rows: [{ title: 'Inputs', value: '-' }],
+ x: 155,
+ y: 12,
+ },
+ {
+ id: 'research',
+ name: 'Research lead',
+ icon: AgentIcon,
+ bgColor: 'var(--text-primary)',
+ rows: [
+ { title: 'Messages', value: '-' },
+ { title: 'Model', value: '-' },
+ ],
+ x: 155,
+ y: 172,
+ },
+ {
+ id: 'score',
+ name: 'Score the fit',
+ icon: ConditionalIcon,
+ bgColor: 'var(--text-secondary)',
+ rows: [{ title: 'Conditions', value: '-' }],
+ x: 155,
+ y: 372,
+ },
+ {
+ id: 'salesforce',
+ name: 'Create in Salesforce',
+ icon: SalesforceIcon,
+ bgColor: '#FFFFFF',
+ tileBorder: true,
+ isTerminal: true,
+ rows: [
+ { title: 'Object', value: '-' },
+ { title: 'Action', value: '-' },
+ ],
+ x: 0,
+ y: 560,
+ },
+ {
+ id: 'notify',
+ name: 'Alert owner',
+ icon: SlackIcon,
+ bgColor: '#611F69',
+ isTerminal: true,
+ rows: [
+ { title: 'Channel', value: '-' },
+ { title: 'Message', value: '-' },
+ ],
+ x: 310,
+ y: 560,
+ },
+ ],
+ stageEdges: [
+ ['start', 'research'],
+ ['research', 'score'],
+ ['score', 'salesforce'],
+ ['score', 'notify'],
+ ],
+ stageCanvas: { width: 560, height: 680 },
+}
+
+/**
+ * The sales hero's platform loop - the shared enterprise loop replayed with
+ * the inbound-lead story above. Client wrapper so the icon-bearing content
+ * object never crosses a server/client boundary.
+ */
+export function SalesHeroLoop() {
+ return
+}
diff --git a/apps/sim/app/(landing)/solutions/sales/page.tsx b/apps/sim/app/(landing)/solutions/sales/page.tsx
new file mode 100644
index 00000000000..15b36cec945
--- /dev/null
+++ b/apps/sim/app/(landing)/solutions/sales/page.tsx
@@ -0,0 +1,21 @@
+import { buildLandingMetadata } from '@/lib/landing/seo'
+import SalesSolution from '@/app/(landing)/solutions/sales/sales'
+
+export const revalidate = 3600
+
+const TITLE = 'AI Agents for Lead Research & CRM Updates | Sim'
+const DESCRIPTION =
+ 'Sales teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate lead research, personalized outreach, and CRM updates.'
+
+export const metadata = buildLandingMetadata({
+ title: TITLE,
+ description: DESCRIPTION,
+ path: '/solutions/sales',
+ keywords:
+ 'AI workspace, AI agents for sales, sales automation, lead research, CRM automation, pipeline reporting, open-source AI agent platform',
+ twitterImageAlt: 'Sim',
+})
+
+export default function Page() {
+ return
+}
diff --git a/apps/sim/app/(landing)/solutions/sales/sales.tsx b/apps/sim/app/(landing)/solutions/sales/sales.tsx
new file mode 100644
index 00000000000..5fb08b5d3c8
--- /dev/null
+++ b/apps/sim/app/(landing)/solutions/sales/sales.tsx
@@ -0,0 +1,159 @@
+import {
+ PlatformHeroVisual,
+ SolutionsPage,
+ type SolutionsPageConfig,
+} from '@/app/(landing)/components'
+import {
+ ItPlatformTeamsGraphic,
+ OperationsTeamsGraphic,
+ RunMonitoringGraphic,
+ StagingGraphic,
+} from '@/app/(landing)/enterprise/components/feature-graphics'
+import {
+ DocumentDraftGraphic,
+ KnowledgeAnswerGraphic,
+} from '@/app/(landing)/solutions/components/feature-graphics'
+import { SalesHeroLoop } from '@/app/(landing)/solutions/sales/components/sales-hero-loop'
+
+/**
+ * Sales solution page - a consumer of {@link SolutionsPage} rendered with
+ * the enterprise page's feature-tile treatment.
+ *
+ * The whole page is one typed {@link SolutionsPageConfig} rendered inside
+ * the shared route-group layout's chrome. Every visual slot carries a
+ * feature graphic in the enterprise design language, retold through the
+ * graphics' content props for sales' use cases - inbound lead routing
+ * across systems, a research brief grounded in real account context,
+ * outreach drafting, CRM stage updates, meeting prep, and the pipeline
+ * digest.
+ */
+const SALES_CONFIG: SolutionsPageConfig = {
+ module: 'Sales',
+ path: '/solutions/sales',
+ hero: {
+ eyebrow: 'Sales',
+ heading: 'Automate lead research, outreach, and CRM updates with Sim agents.',
+ description:
+ 'Sales teams build AI agents in Sim, the open-source AI workspace, wired into Salesforce, HubSpot, and 1,000+ integrations, so reps spend their time selling, not updating records.',
+ summary:
+ 'Sim is the open-source AI workspace where sales teams build, deploy, and manage AI agents that automate lead research, personalized outreach, and CRM updates, wired into Salesforce, HubSpot, and 1,000+ integrations so the pipeline stays current and reps spend their time selling.',
+ visual: (
+
+
+
+ ),
+ },
+ rows: [
+ {
+ id: 'pipeline',
+ title: 'Fill the pipeline.',
+ subtitle: 'Sim agents handle research, outreach, and follow-up around the clock.',
+ cta: { label: 'See sales agents', href: '/signup' },
+ cards: [
+ {
+ title: 'Route inbound leads',
+ description: 'Sim scores, routes, and follows up on new leads the moment they arrive.',
+ featureTileTone: 'dark',
+ featureTileDescriptionTone: 'soft',
+ visual: (
+
+ ),
+ },
+ {
+ title: 'Research every lead',
+ description:
+ 'Sim researches the company, the news, and the stack, and writes the brief before you call.',
+ visual: (
+
+ ),
+ },
+ {
+ title: 'Draft outreach',
+ description:
+ 'Sim drafts personalized outbound from the research, in your voice, ready to send.',
+ visual: (
+
+ ),
+ },
+ ],
+ },
+ {
+ id: 'crm',
+ title: 'Keep the CRM true.',
+ subtitle: 'Sim keeps records current so the forecast is built on real data.',
+ cta: { label: 'Explore CRM automation', href: '/signup' },
+ cards: [
+ {
+ title: 'Update the CRM',
+ description: 'Sim logs calls, sets next steps, and moves stages after every touchpoint.',
+ visual: (
+
+ ),
+ },
+ {
+ title: 'Prep every meeting',
+ description: 'Sim assembles a brief before every call from your CRM, email, and notes.',
+ visual: (
+
+ ),
+ },
+ {
+ title: 'Report the pipeline',
+ description: 'Sim assembles pipeline and forecast digests from your CRM on schedule.',
+ visual: (
+
+ ),
+ },
+ ],
+ },
+ ],
+}
+
+export default function SalesSolution() {
+ return
+}
diff --git a/apps/sim/app/sitemap.ts b/apps/sim/app/sitemap.ts
index e05670f1cfc..b468d883742 100644
--- a/apps/sim/app/sitemap.ts
+++ b/apps/sim/app/sitemap.ts
@@ -104,6 +104,9 @@ export default async function sitemap(): Promise
{
{
url: `${baseUrl}/solutions/it`,
},
+ {
+ url: `${baseUrl}/solutions/sales`,
+ },
{
url: `${baseUrl}/blog`,
lastModified: latestPostDateValue,