Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
95dea25
refactor(web): restructure landing around an "agent is a directory" n…
claude Jun 26, 2026
f663ef4
refactor(web): re-architect the landing IA around eve's full page str…
claude Jun 26, 2026
43584a8
refactor(web): ground the landing in real product facts + add binding…
claude Jun 26, 2026
fe9d3e2
refactor(web): adopt eve's hero toggle + alternating code walkthrough
claude Jun 26, 2026
f71f4ff
refactor(web): eve-style stacked production cards + two-column primit…
claude Jun 26, 2026
4a4e261
fix(web): replace the sparse alternating walkthrough with a compact f…
claude Jun 26, 2026
5518ee8
feat(web): premium code windows + typed hero terminal
claude Jun 26, 2026
3fa3c5d
refactor(web): rebuild hero + walkthrough to match the real eve layout
claude Jun 26, 2026
7750309
refactor(web): eve-style 3-column production + shorten the page
claude Jun 26, 2026
0180014
refactor(web): give the directory walkthrough panel equal weight
claude Jun 26, 2026
e6f19e8
refactor(web): match eve's sticky-swap walkthrough animation
claude Jun 26, 2026
4de88a3
style(web): more breathing room between walkthrough steps
claude Jun 26, 2026
c1b01a9
content(web): richer markdown bodies in the directory walkthrough
claude Jun 26, 2026
09e40ba
refactor(web): eve-style "built on primitives" with product cards + C…
claude Jun 26, 2026
d773fd4
feat(web): make the hero command copyable + stop the toggle layout bump
claude Jun 26, 2026
1c663ae
refactor(web): fill the hero agent card + align the production columns
claude Jun 26, 2026
d29de54
copy(web): final CTA headline → "Give it a sandbox. Watch it work."
claude Jun 26, 2026
e150694
refactor(marketing): tighten landing density and unify production mocks
claude Jun 26, 2026
9e3be64
fix(marketing): ground landing copy in real codebase facts
claude Jun 26, 2026
d67a562
refactor(marketing): de-dupe landing narrative, unify on outname's terms
claude Jun 26, 2026
8ec0079
feat(marketing): add brand logos to integrations and inference providers
claude Jun 26, 2026
c8fe80e
feat(marketing): real brand marks for Neon and the custom-logo integr…
claude Jun 26, 2026
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
5 changes: 4 additions & 1 deletion packages/shared/doctor.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
"ignore": {
"overrides": [
{
"files": ["marketing/components/landing/composable-workbench/**"],
"files": [
"marketing/components/landing/agent-anatomy/**",
"marketing/components/landing/landing-primitives.tsx"
],
"rules": [
"react-doctor/design-no-em-dash-in-jsx-text",
"react-doctor/design-no-redundant-padding-axes",
Expand Down
24 changes: 22 additions & 2 deletions packages/shared/marketing/components/landing-home-page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
'use client'

import { LandingComposableWorkbench } from '@outname/shared/marketing/components/landing/composable-workbench/landing-composable-workbench'
import { LandingAgentAnatomy } from '@outname/shared/marketing/components/landing/agent-anatomy/landing-agent-anatomy'
import { LandingBindings } from '@outname/shared/marketing/components/landing/landing-bindings'
import { LandingChatShowcase } from '@outname/shared/marketing/components/landing/landing-chat-showcase'
import { LandingFinalCta } from '@outname/shared/marketing/components/landing/landing-final-cta'
import { LandingFooter } from '@outname/shared/marketing/components/landing/landing-footer'
import { LandingHeartbeatCloser } from '@outname/shared/marketing/components/landing/landing-heartbeat-closer'
import { LandingHeroDemo } from '@outname/shared/marketing/components/landing/landing-hero-demo'
import { LandingNav } from '@outname/shared/marketing/components/landing/landing-nav'
import { LandingPrimitives } from '@outname/shared/marketing/components/landing/landing-primitives'
import { LandingProductionIntro } from '@outname/shared/marketing/components/landing/landing-production-intro'
import { useReducedMotion } from 'motion/react'

export function LandingHomePage() {
Expand All @@ -16,10 +20,26 @@ export function LandingHomePage() {
<main className="relative isolate overflow-x-clip bg-background text-foreground">
<LandingNav />

{/* 1 — Positioning, command, and the directory artifact */}
<LandingHeroDemo shouldReduceMotion={reduceMotionFlag} />

{/* 2 — An agent is a directory: overview + alternating file walkthrough */}
<LandingAgentAnatomy shouldReduceMotion={reduceMotionFlag} />

{/* 3 — What you bind around the folder */}
<LandingBindings shouldReduceMotion={reduceMotionFlag} />

{/* 4 — What it's built on */}
<LandingPrimitives shouldReduceMotion={reduceMotionFlag} />

{/* 5 — Production readiness, then proven live */}
<LandingProductionIntro shouldReduceMotion={reduceMotionFlag} />
<LandingChatShowcase shouldReduceMotion={reduceMotionFlag} />
<LandingComposableWorkbench shouldReduceMotion={reduceMotionFlag} />
<LandingHeartbeatCloser shouldReduceMotion={reduceMotionFlag} />

{/* 6 — Final call to action */}
<LandingFinalCta shouldReduceMotion={reduceMotionFlag} />

<LandingFooter />
</main>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import {
type AgentTreeNode,
type AnatomyStepId,
agentSlug,
agentTree,
type FileOwner,
} from '@outname/shared/marketing/data/agent-anatomy'
import { cn } from '@outname/ui/lib/utils'
import { FileTextIcon, FolderIcon } from 'lucide-react'

const DEPTH_INDENT_REM = 0.75

const ownerDot: Record<FileOwner, string> = {
agent: 'border border-current opacity-50',
shared: 'bg-current opacity-50',
user: 'bg-brand',
}

function TreeRow({ active, node }: { active: boolean; node: AgentTreeNode }) {
const Icon = node.kind === 'dir' ? FolderIcon : FileTextIcon
const isStepNode = Boolean(node.stepId)

return (
<li>
<span
className={cn(
'ease flex items-center gap-2 border-l-2 py-1.5 pr-3 font-mono text-xs tracking-normal transition-colors duration-200',
active
? 'border-brand bg-foreground text-background'
: 'border-transparent text-muted-foreground'
)}
style={{ paddingLeft: `${node.depth * DEPTH_INDENT_REM + 0.5}rem` }}
>
<Icon
className={cn(
'size-3.5 shrink-0',
active ? 'text-background' : 'text-muted-foreground'
)}
/>
<span
className={cn(
'truncate',
active && 'font-semibold',
!(active || isStepNode) && 'opacity-70'
)}
>
{node.label}
</span>
{node.owner ? (
<span
aria-hidden
className={cn('ml-auto size-2 shrink-0', ownerDot[node.owner])}
/>
) : null}
</span>
</li>
)
}

export function AgentFileTree({
activeStepId,
className,
}: {
activeStepId?: AnatomyStepId
className?: string
}) {
return (
<div className={cn('border border-border bg-background', className)}>
<div className="flex items-center gap-2 border-border border-b px-4 py-3">
<span aria-hidden className="size-2.5 shrink-0 bg-brand" />
<span className="truncate font-mono text-xs tracking-normal">
{agentSlug}/
</span>
<span className="swiss-label ml-auto text-muted-foreground">
sandbox
</span>
</div>
<ul className="py-2">
{agentTree.map((node) => (
<TreeRow
active={Boolean(node.stepId && node.stepId === activeStepId)}
key={node.id}
node={node}
/>
))}
</ul>
<div className="flex items-center gap-4 border-border border-t px-4 py-2.5 font-mono text-[10px] text-muted-foreground tracking-normal">
<span className="flex items-center gap-1.5">
<span aria-hidden className="size-2 bg-brand" /> you author
</span>
<span className="flex items-center gap-1.5">
<span
aria-hidden
className="size-2 border border-muted-foreground opacity-50"
/>{' '}
agent writes
</span>
</div>
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { cn } from '@outname/ui/lib/utils'

export function AnatomyCodeBlock({
code,
className,
}: {
code: string
className?: string
}) {
return (
<pre
className={cn(
'overflow-x-auto border border-border bg-muted p-4 font-mono text-[11px] text-foreground leading-relaxed sm:text-xs',
className
)}
>
<code>{code}</code>
</pre>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { AnatomyStepId } from '@outname/shared/marketing/data/agent-anatomy'
import {
BrainIcon,
CalendarIcon,
ContactIcon,
ListChecksIcon,
type LucideIcon,
MoonIcon,
ScrollTextIcon,
SparklesIcon,
TargetIcon,
UserIcon,
} from 'lucide-react'

export const stepIcons: Record<AnatomyStepId, LucideIcon> = {
calendar: CalendarIcon,
dreams: MoonIcon,
goals: TargetIcon,
identity: ContactIcon,
instructions: ScrollTextIcon,
memory: BrainIcon,
soul: SparklesIcon,
tasks: ListChecksIcon,
user: UserIcon,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
'use client'

import {
revealVariants,
staggerVariants,
} from '@outname/shared/marketing/components/landing/landing-motion'
import {
type AnatomyStep,
anatomyStepCount,
anatomySteps,
ownerLabel,
} from '@outname/shared/marketing/data/agent-anatomy'
import { Badge } from '@outname/ui/components/ui/badge'
import { cn } from '@outname/ui/lib/utils'
import { domAnimation, LazyMotion, m as motion } from 'motion/react'
import { AgentFileTree } from './agent-file-tree'
import { AnatomyCodeBlock } from './anatomy-step-detail'
import { stepIcons } from './constants'

function DirectoryOverview() {
return (
<motion.div
className="mt-10 grid gap-5 lg:grid-cols-[minmax(0,20rem)_minmax(0,1fr)] lg:items-start"
variants={revealVariants}
>
<AgentFileTree />
<ol className="grid gap-px self-stretch border border-border bg-border sm:grid-cols-2 [&>li:last-child]:sm:col-span-2">
{anatomySteps.map((step) => (
<li key={step.id}>
<a
className="ease flex h-full items-baseline gap-3 bg-background px-4 py-3 transition-colors duration-150 hover:bg-muted"
href={`#anatomy-${step.id}`}
>
<span className="font-mono text-[11px] text-muted-foreground tabular-nums">
{step.index}
</span>
<span className="min-w-0">
<span className="block font-mono text-xs">
{fileNameFor(step)}
</span>
<span className="mt-0.5 block text-muted-foreground text-xs leading-snug">
{step.title}
</span>
</span>
</a>
</li>
))}
</ol>
</motion.div>
)
}

const fileLabels: Record<string, string> = {
calendar: 'CALENDAR.md',
dreams: 'DREAMS.md',
goals: 'GOALS.md',
identity: 'IDENTITY.md',
instructions: 'AGENTS.md',
memory: 'MEMORY.md',
soul: 'SOUL.md',
tasks: 'TASKS.md',
user: 'USER.md',
}

function fileNameFor(step: AnatomyStep): string {
return fileLabels[step.node] ?? step.node
}

function AnatomyRow({ step, index }: { step: AnatomyStep; index: number }) {
const Icon = stepIcons[step.id]
const codeOnLeft = index % 2 === 1

return (
<motion.li
className="border-border border-t pt-10 md:pt-14"
id={`anatomy-${step.id}`}
variants={revealVariants}
>
<div className="grid gap-8 md:grid-cols-2 md:gap-12 lg:items-center">
<div className={cn(codeOnLeft && 'md:order-2')}>
<div className="flex items-center gap-4">
<span className="font-mono text-2xl text-muted-foreground tabular-nums">
{step.index}
</span>
<span className="grid size-10 place-items-center border border-border bg-brand text-brand-foreground">
<Icon className="size-4" />
</span>
<span className="font-mono text-muted-foreground text-xs">
{fileNameFor(step)}
</span>
</div>
<h3 className="mt-6 text-balance font-semibold text-2xl leading-tight tracking-tight md:text-3xl">
{step.title}
</h3>
<p className="mt-4 max-w-md text-muted-foreground leading-relaxed">
{step.caption}
</p>
<div className="mt-6 flex flex-wrap items-center gap-2">
<Badge
className={cn(
step.owner === 'user' &&
'border-transparent bg-brand text-brand-foreground'
)}
variant={step.owner === 'user' ? 'default' : 'outline'}
>
{ownerLabel[step.owner]}
</Badge>
<span className="swiss-label text-muted-foreground">
{step.note}
</span>
</div>
</div>
<div className={cn(codeOnLeft && 'md:order-1')}>
<AnatomyCodeBlock code={step.code} />
</div>
</div>
</motion.li>
)
}

export function LandingAgentAnatomy({
shouldReduceMotion,
}: {
shouldReduceMotion: boolean
}) {
return (
<section
className="px-4 py-20 sm:px-6 md:px-10 md:py-28 lg:px-12"
id="anatomy"
>
<LazyMotion features={domAnimation}>
<motion.div
className="mx-auto max-w-7xl"
initial={shouldReduceMotion ? false : 'hidden'}
variants={staggerVariants}
viewport={{ margin: '-80px', once: true }}
whileInView="visible"
>
<motion.div
className="grid gap-5 border-border border-t pt-5 md:grid-cols-[minmax(0,0.82fr)_minmax(0,1fr)] md:items-end"
variants={revealVariants}
>
<div>
<p className="swiss-label text-muted-foreground">
The mental model
</p>
<h2 className="mt-4 text-balance font-semibold text-3xl leading-tight tracking-tight md:text-4xl">
An agent is a directory.
</h2>
</div>
<p className="max-w-2xl text-muted-foreground leading-relaxed">
Nine canonical markdown files in a sandbox, each with a job. Some
you author; the rest the agent keeps current itself. No black box
— every file is one you could open and edit.
</p>
</motion.div>

<DirectoryOverview />

<ol className="mt-16 grid gap-0">
{anatomySteps.map((step, index) => (
<AnatomyRow index={index} key={step.id} step={step} />
))}
</ol>

<motion.p
className="mt-12 border-border border-t pt-6 font-mono text-[11px] text-muted-foreground tracking-normal"
variants={revealVariants}
>
{anatomyStepCount} files · one folder you can read end to end
</motion.p>
</motion.div>
</LazyMotion>
</section>
)
}
Loading