Skip to content
Merged
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
2 changes: 1 addition & 1 deletion apps/sim/app/(landing)/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export default async function Page({ params }: { params: Promise<{ slug: string
<h3 className='font-[430] font-season text-lg text-white leading-tight tracking-[-0.01em]'>
{p.title}
</h3>
<p className='line-clamp-2 text-[#F6F6F0]/50 text-sm leading-[150%]'>
<p className='line-clamp-2 text-[var(--landing-text-muted)] text-sm leading-[150%]'>
{p.description}
</p>
</div>
Expand Down
6 changes: 3 additions & 3 deletions apps/sim/app/(landing)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export default async function BlogIndex({
<h1 className='text-balance font-[430] font-season text-[28px] text-white leading-[100%] tracking-[-0.02em] lg:text-[40px]'>
Latest from Sim
</h1>
<p className='max-w-[360px] font-[430] font-season text-[#F6F6F0]/50 text-sm leading-[150%] tracking-[0.02em] lg:text-base'>
<p className='max-w-[540px] font-[430] font-season text-[var(--landing-text-muted)] text-sm leading-[150%] tracking-[0.02em] lg:text-base'>
Announcements, insights, and guides for building AI agent workflows.
</p>
</div>
Expand Down Expand Up @@ -152,7 +152,7 @@ export default async function BlogIndex({
<h3 className='font-[430] font-season text-lg text-white leading-tight tracking-[-0.01em]'>
{p.title}
</h3>
<p className='line-clamp-2 text-[#F6F6F0]/50 text-sm leading-[150%]'>
<p className='line-clamp-2 text-[var(--landing-text-muted)] text-sm leading-[150%]'>
{p.description}
</p>
</div>
Expand Down Expand Up @@ -191,7 +191,7 @@ export default async function BlogIndex({
<h3 className='font-[430] font-season text-base text-white leading-tight tracking-[-0.01em] lg:text-lg'>
{p.title}
</h3>
<p className='line-clamp-2 text-[#F6F6F0]/40 text-sm leading-[150%]'>
<p className='line-clamp-2 text-[var(--landing-text-muted)] text-sm leading-[150%]'>
{p.description}
</p>
</div>
Expand Down
2 changes: 0 additions & 2 deletions apps/sim/app/(landing)/components/footer/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,8 @@ const INTEGRATION_LINKS: FooterItem[] = [
{ label: 'Linear', href: 'https://docs.sim.ai/tools/linear', external: true },
{ label: 'Airtable', href: 'https://docs.sim.ai/tools/airtable', external: true },
{ label: 'Firecrawl', href: 'https://docs.sim.ai/tools/firecrawl', external: true },
{ label: 'Pinecone', href: 'https://docs.sim.ai/tools/pinecone', external: true },
{ label: 'Discord', href: 'https://docs.sim.ai/tools/discord', external: true },
{ label: 'Microsoft Teams', href: 'https://docs.sim.ai/tools/microsoft_teams', external: true },
{ label: 'Outlook', href: 'https://docs.sim.ai/tools/outlook', external: true },
{ label: 'Telegram', href: 'https://docs.sim.ai/tools/telegram', external: true },
]

Expand Down
46 changes: 34 additions & 12 deletions apps/sim/app/(landing)/components/landing-faq.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client'

import { useState } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { ChevronDown } from '@/components/emcn'
import { cn } from '@/lib/core/utils/cn'

Expand All @@ -15,46 +16,67 @@ interface LandingFAQProps {

export function LandingFAQ({ faqs }: LandingFAQProps) {
const [openIndex, setOpenIndex] = useState<number | null>(0)
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)

return (
<div className='divide-y divide-[var(--landing-border)]'>
<div>
{faqs.map(({ question, answer }, index) => {
const isOpen = openIndex === index
const isHovered = hoveredIndex === index
const showDivider = index > 0 && hoveredIndex !== index && hoveredIndex !== index - 1

return (
<div key={question}>
<div
className={cn(
'h-px w-full bg-[var(--landing-bg-elevated)]',
index === 0 || !showDivider ? 'invisible' : 'visible'
)}
/>
<button
type='button'
onClick={() => setOpenIndex(isOpen ? null : index)}
className='flex w-full items-start justify-between gap-4 py-5 text-left'
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
className='-mx-6 flex w-[calc(100%+3rem)] items-center justify-between gap-4 px-6 py-4 text-left transition-colors hover:bg-[var(--landing-bg-elevated)]'
aria-expanded={isOpen}
>
<span
className={cn(
'font-[500] text-[15px] leading-snug transition-colors',
'text-[15px] leading-snug tracking-[-0.02em] transition-colors',
isOpen
? 'text-[var(--landing-text)]'
: 'text-[var(--landing-text-muted)] hover:text-[var(--landing-text)]'
: 'text-[var(--landing-text-body)] hover:text-[var(--landing-text)]'
)}
>
{question}
</span>
<ChevronDown
className={cn(
'mt-0.5 h-4 w-4 shrink-0 text-[#555] transition-transform duration-200',
'h-3 w-3 shrink-0 text-[var(--landing-text-subtle)] transition-transform duration-200',
isOpen ? 'rotate-180' : 'rotate-0'
)}
aria-hidden='true'
/>
</button>

{isOpen && (
<div className='pb-5'>
<p className='text-[14px] text-[var(--landing-text-muted)] leading-[1.75]'>
{answer}
</p>
</div>
)}
<AnimatePresence initial={false}>
{isOpen && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.25, ease: [0.4, 0, 0.2, 1] }}
className='overflow-hidden'
>
<div className='pt-2 pb-4'>
<p className='text-[14px] text-[var(--landing-text-body)] leading-[1.75]'>
{answer}
</p>
</div>
</motion.div>
)}
</AnimatePresence>
</div>
)
})}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import type { ComponentType, SVGProps } from 'react'
import Link from 'next/link'
import {
AgentIcon,
ApiIcon,
McpIcon,
PackageSearchIcon,
TableIcon,
WorkflowIcon,
} from '@/components/icons'

interface ProductLink {
label: string
description: string
href: string
external?: boolean
icon: ComponentType<SVGProps<SVGSVGElement>>
}

interface SidebarLink {
label: string
href: string
external?: boolean
}

const PLATFORM: ProductLink[] = [
{
label: 'Workflows',
description: 'Visual AI automation builder',
href: 'https://docs.sim.ai/getting-started',
external: true,
icon: WorkflowIcon,
},
{
label: 'Agent',
description: 'Build autonomous AI agents',
href: 'https://docs.sim.ai/blocks/agent',
external: true,
icon: AgentIcon,
},
{
label: 'MCP',
description: 'Connect external tools',
href: 'https://docs.sim.ai/mcp',
external: true,
icon: McpIcon,
},
{
label: 'Knowledge Base',
description: 'Retrieval-augmented context',
href: 'https://docs.sim.ai/knowledgebase',
external: true,
icon: PackageSearchIcon,
},
{
label: 'Tables',
description: 'Structured data storage',
href: 'https://docs.sim.ai/tables',
external: true,
icon: TableIcon,
},
{
label: 'API',
description: 'Deploy workflows as endpoints',
href: 'https://docs.sim.ai/api-reference/getting-started',
external: true,
icon: ApiIcon,
},
]

const EXPLORE: SidebarLink[] = [
{ label: 'Models', href: '/models' },
{ label: 'Integrations', href: '/integrations' },
{ label: 'Changelog', href: '/changelog' },
{ label: 'Self-hosting', href: 'https://docs.sim.ai/self-hosting', external: true },
]

function DropdownLink({ link }: { link: ProductLink }) {
const Icon = link.icon
const Tag = link.external ? 'a' : Link
const props = link.external
? { href: link.href, target: '_blank' as const, rel: 'noopener noreferrer' }
: { href: link.href }

return (
<Tag
{...props}
className='group/item flex items-start gap-2.5 rounded-[5px] px-2.5 py-2 transition-colors hover:bg-[var(--landing-bg-elevated)]'
>
<Icon className='mt-0.5 h-[15px] w-[15px] shrink-0 text-[var(--landing-text-icon)]' />
<div className='flex flex-col'>
<span className='font-[430] font-season text-[13px] text-white leading-tight'>
{link.label}
</span>
<span className='font-season text-[12px] text-[var(--landing-text-subtle)] leading-[150%]'>
{link.description}
</span>
</div>
</Tag>
)
}

export function ProductDropdown() {
return (
<div className='flex w-[560px] rounded-[5px] border border-[var(--landing-bg-elevated)] bg-[var(--landing-bg)] shadow-overlay'>
<div className='flex-1 p-2'>
<div className='mb-1 px-2.5 pt-1'>
<span className='font-[430] font-season text-[11px] text-[var(--landing-text-subtle)] uppercase tracking-[0.08em]'>
Platform
</span>
<div className='mt-1.5 h-px bg-[var(--landing-bg-elevated)]' />
</div>

<div className='grid grid-cols-2'>
{PLATFORM.map((link) => (
<DropdownLink key={link.label} link={link} />
))}
</div>
</div>

<div className='w-px self-stretch bg-[var(--landing-bg-elevated)]' />

<div className='w-[160px] p-2'>
<div className='mb-1 px-2.5 pt-1'>
<span className='font-[430] font-season text-[11px] text-[var(--landing-text-subtle)] uppercase tracking-[0.08em]'>
Explore
</span>
<div className='mt-1.5 h-px bg-[var(--landing-bg-elevated)]' />
</div>

{EXPLORE.map((link) => {
const Tag = link.external ? 'a' : Link
const props = link.external
? { href: link.href, target: '_blank' as const, rel: 'noopener noreferrer' }
: { href: link.href }
return (
<Tag
key={link.label}
{...props}
className='block rounded-[5px] px-2.5 py-1.5 font-[430] font-season text-[13px] text-white transition-colors hover:bg-[var(--landing-bg-elevated)]'
>
{link.label}
</Tag>
)
})}
</div>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import { useRouter } from 'next/navigation'
import { LandingPromptStorage } from '@/lib/core/utils/browser-storage'
import { cn } from '@/lib/core/utils/cn'

interface TemplateCardButtonProps {
prompt: string
className?: string
children: React.ReactNode
}

export function TemplateCardButton({ prompt, children }: TemplateCardButtonProps) {
export function TemplateCardButton({ prompt, className, children }: TemplateCardButtonProps) {
const router = useRouter()

function handleClick() {
Expand All @@ -17,11 +19,7 @@ export function TemplateCardButton({ prompt, children }: TemplateCardButtonProps
}

return (
<button
type='button'
onClick={handleClick}
className='group flex w-full flex-col items-start rounded-lg border border-[var(--landing-border)] bg-[var(--landing-bg-card)] p-5 text-left transition-colors hover:border-[var(--landing-border-strong)] hover:bg-[var(--landing-bg-elevated)]'
>
<button type='button' onClick={handleClick} className={cn('w-full text-left', className)}>
{children}
</button>
)
Expand Down
Loading
Loading