Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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