fix(website): simplify landing page and improve UX
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import * as React from 'react'
|
||||
import { createFileRoute } from '@tanstack/react-router'
|
||||
import { CursorFieldProvider, FloatingButterfly } from '~/components/butterfly'
|
||||
import { CursorFieldProvider } from '~/components/butterfly'
|
||||
import '~/styles.css'
|
||||
|
||||
export const Route = createFileRoute('/')({
|
||||
@@ -27,51 +28,7 @@ function Home() {
|
||||
<div className="absolute inset-0 bg-background/80" />
|
||||
<div className="absolute inset-x-0 bottom-0 h-32 bg-gradient-to-t from-black to-transparent" />
|
||||
|
||||
{/* Left side butterflies - facing right */}
|
||||
<FloatingButterfly
|
||||
style={{ left: '5%', top: '15%' }}
|
||||
size={38}
|
||||
color="#e8976b"
|
||||
delay={0}
|
||||
duration={0.45}
|
||||
direction="right"
|
||||
/>
|
||||
<FloatingButterfly
|
||||
style={{ left: '8%', top: '45%' }}
|
||||
size={30}
|
||||
color="#f0c75e"
|
||||
delay={0.3}
|
||||
duration={0.55}
|
||||
direction="right"
|
||||
/>
|
||||
<FloatingButterfly
|
||||
style={{ left: '3%', top: '70%' }}
|
||||
size={34}
|
||||
color="#d4728a"
|
||||
delay={0.15}
|
||||
duration={0.5}
|
||||
direction="left"
|
||||
/>
|
||||
|
||||
{/* Right side butterflies - facing left */}
|
||||
<FloatingButterfly
|
||||
style={{ right: '6%', top: '20%' }}
|
||||
size={32}
|
||||
color="#f5d86a"
|
||||
delay={0.2}
|
||||
duration={0.6}
|
||||
direction="left"
|
||||
/>
|
||||
<FloatingButterfly
|
||||
style={{ right: '4%', top: '55%' }}
|
||||
size={40}
|
||||
color="#e07850"
|
||||
delay={0.1}
|
||||
duration={0.4}
|
||||
direction="left"
|
||||
/>
|
||||
|
||||
<div className="relative p-5 md:p-16 max-w-2xl mx-auto">
|
||||
<div className="relative p-6 md:p-20 max-w-3xl mx-auto">
|
||||
<Nav />
|
||||
<Hero />
|
||||
<GetStarted />
|
||||
@@ -80,10 +37,10 @@ function Home() {
|
||||
|
||||
{/* Content section with black background */}
|
||||
<div className="bg-black">
|
||||
<main className="p-5 md:p-16 max-w-2xl mx-auto">
|
||||
<main className="p-6 md:p-20 max-w-3xl mx-auto">
|
||||
<Features />
|
||||
<Story />
|
||||
<FAQ />
|
||||
<Footer />
|
||||
</main>
|
||||
</div>
|
||||
</CursorFieldProvider>
|
||||
@@ -95,7 +52,7 @@ function Nav() {
|
||||
<nav className="flex items-center justify-between mb-16">
|
||||
<div className="flex items-center gap-3">
|
||||
<img src="/logo.svg" alt="Paseo" className="w-7 h-7" />
|
||||
<span className="text-lg font-medium">paseo</span>
|
||||
<span className="text-lg font-medium">Paseo</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<a
|
||||
@@ -108,8 +65,17 @@ function Nav() {
|
||||
href="https://github.com/moboudra/paseo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors"
|
||||
className="text-sm text-muted-foreground hover:text-foreground transition-colors flex items-center gap-1.5"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 -0.5 25 25"
|
||||
>
|
||||
<path d="m12.301 0h.093c2.242 0 4.34.613 6.137 1.68l-.055-.031c1.871 1.094 3.386 2.609 4.449 4.422l.031.058c1.04 1.769 1.654 3.896 1.654 6.166 0 5.406-3.483 10-8.327 11.658l-.087.026c-.063.02-.135.031-.209.031-.162 0-.312-.054-.433-.144l.002.001c-.128-.115-.208-.281-.208-.466 0-.005 0-.01 0-.014v.001q0-.048.008-1.226t.008-2.154c.007-.075.011-.161.011-.249 0-.792-.323-1.508-.844-2.025.618-.061 1.176-.163 1.718-.305l-.076.017c.573-.16 1.073-.373 1.537-.642l-.031.017c.508-.28.938-.636 1.292-1.058l.006-.007c.372-.476.663-1.036.84-1.645l.009-.035c.209-.683.329-1.468.329-2.281 0-.045 0-.091-.001-.136v.007c0-.022.001-.047.001-.072 0-1.248-.482-2.383-1.269-3.23l.003.003c.168-.44.265-.948.265-1.479 0-.649-.145-1.263-.404-1.814l.011.026c-.115-.022-.246-.035-.381-.035-.334 0-.649.078-.929.216l.012-.005c-.568.21-1.054.448-1.512.726l.038-.022-.609.384c-.922-.264-1.981-.416-3.075-.416s-2.153.152-3.157.436l.081-.02q-.256-.176-.681-.433c-.373-.214-.814-.421-1.272-.595l-.066-.022c-.293-.154-.64-.244-1.009-.244-.124 0-.246.01-.364.03l.013-.002c-.248.524-.393 1.139-.393 1.788 0 .531.097 1.04.275 1.509l-.01-.029c-.785.844-1.266 1.979-1.266 3.227 0 .025 0 .051.001.076v-.004c-.001.039-.001.084-.001.13 0 .809.12 1.591.344 2.327l-.015-.057c.189.643.476 1.202.85 1.693l-.009-.013c.354.435.782.793 1.267 1.062l.022.011c.432.252.933.465 1.46.614l.046.011c.466.125 1.024.227 1.595.284l.046.004c-.431.428-.718 1-.784 1.638l-.001.012c-.207.101-.448.183-.699.236l-.021.004c-.256.051-.549.08-.85.08-.022 0-.044 0-.066 0h.003c-.394-.008-.756-.136-1.055-.348l.006.004c-.371-.259-.671-.595-.881-.986l-.007-.015c-.198-.336-.459-.614-.768-.827l-.009-.006c-.225-.169-.49-.301-.776-.38l-.016-.004-.32-.048c-.023-.002-.05-.003-.077-.003-.14 0-.273.028-.394.077l.007-.003q-.128.072-.08.184c.039.086.087.16.145.225l-.001-.001c.061.072.13.135.205.19l.003.002.112.08c.283.148.516.354.693.603l.004.006c.191.237.359.505.494.792l.01.024.16.368c.135.402.38.738.7.981l.005.004c.3.234.662.402 1.057.478l.016.002c.33.064.714.104 1.106.112h.007c.045.002.097.002.15.002.261 0 .517-.021.767-.062l-.027.004.368-.064q0 .609.008 1.418t.008.873v.014c0 .185-.08.351-.208.466h-.001c-.119.089-.268.143-.431.143-.075 0-.147-.011-.214-.032l.005.001c-4.929-1.689-8.409-6.283-8.409-11.69 0-2.268.612-4.393 1.681-6.219l-.032.058c1.094-1.871 2.609-3.386 4.422-4.449l.058-.031c1.739-1.034 3.835-1.645 6.073-1.645h.098-.005zm-7.64 17.666q.048-.112-.112-.192-.16-.048-.208.032-.048.112.112.192.144.096.208-.032zm.497.545q.112-.08-.032-.256-.16-.144-.256-.048-.112.08.032.256.159.157.256.047zm.48.72q.144-.112 0-.304-.128-.208-.272-.096-.144.08 0 .288t.272.112zm.672.673q.128-.128-.064-.304-.192-.192-.32-.048-.144.128.064.304.192.192.32.044zm.913.4q.048-.176-.208-.256-.24-.064-.304.112t.208.24q.24.097.304-.096zm1.009.08q0-.208-.272-.176-.256 0-.256.176 0 .208.272.176.256.001.256-.175zm.929-.16q-.032-.176-.288-.144-.256.048-.224.24t.288.128.225-.224z" />
|
||||
</svg>
|
||||
GitHub
|
||||
</a>
|
||||
</div>
|
||||
@@ -120,8 +86,8 @@ function Nav() {
|
||||
function Hero() {
|
||||
return (
|
||||
<div className="space-y-6">
|
||||
<h1 className="text-4xl md:text-5xl font-medium tracking-tight font-serif">
|
||||
Manage coding agents from your phone and desktop.
|
||||
<h1 className="text-4xl md:text-5xl font-medium tracking-tight">
|
||||
Manage coding agents from your phone and desktop
|
||||
</h1>
|
||||
<p className="text-white/70 text-lg leading-relaxed">
|
||||
Agents run on your machine with your full dev environment. Connect from
|
||||
@@ -174,6 +140,14 @@ function Features() {
|
||||
title="Cross-device"
|
||||
description="Jump seamlessly between iOS, Android, desktop, web, and CLI."
|
||||
/>
|
||||
<Feature
|
||||
title="Git integration"
|
||||
description="Run agents in isolated worktrees. Review diffs and ship directly from the app."
|
||||
/>
|
||||
<Feature
|
||||
title="Open source"
|
||||
description="Free and open source. Run it yourself, fork it, contribute."
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -188,7 +162,7 @@ function Feature({
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-1">
|
||||
<p className="font-medium text-sm">{title}</p>
|
||||
<p className="font-medium text-base">{title}</p>
|
||||
<p className="text-sm text-white/60">{description}</p>
|
||||
</div>
|
||||
)
|
||||
@@ -238,12 +212,73 @@ function Step({
|
||||
}
|
||||
|
||||
function CodeBlock({ children }: { children: React.ReactNode }) {
|
||||
const [copied, setCopied] = React.useState(false)
|
||||
const text = typeof children === 'string' ? children : ''
|
||||
|
||||
function handleCopy() {
|
||||
navigator.clipboard.writeText(text)
|
||||
setCopied(true)
|
||||
setTimeout(() => setCopied(false), 2000)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-card border border-border rounded-lg p-3 md:p-4 font-mono text-sm flex items-center justify-between gap-2">
|
||||
<div className="bg-card rounded-lg p-3 md:p-4 font-mono text-sm flex items-center justify-between gap-2">
|
||||
<div>
|
||||
<span className="text-muted-foreground select-none">$ </span>
|
||||
<span className="text-foreground">{children}</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={handleCopy}
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-1"
|
||||
title="Copy to clipboard"
|
||||
>
|
||||
{copied ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 256 256"
|
||||
>
|
||||
<path d="M216,28H88A20,20,0,0,0,68,48V76H40A20,20,0,0,0,20,96V216a20,20,0,0,0,20,20H168a20,20,0,0,0,20-20V188h28a20,20,0,0,0,20-20V48A20,20,0,0,0,216,28ZM164,212H44V100H164Zm48-48H188V96a20,20,0,0,0-20-20H92V52H212Z" />
|
||||
</svg>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Story() {
|
||||
return (
|
||||
<div className="pt-12 space-y-4 text-sm text-white/60">
|
||||
<p>
|
||||
I've been using Claude Code since launch. Once I realized I could check
|
||||
on agents from my phone, I started spending a lot more time outside
|
||||
instead of waiting at my desk. I'd SSH into Tmux from Termux on Android.
|
||||
It worked, but the UX was rough. Dictation was bad, the keyboard was
|
||||
awkward, and the infamous scroll bug meant starting over constantly.
|
||||
</p>
|
||||
<p>
|
||||
Anthropic and OpenAI added coding agents to their mobile apps, but they
|
||||
force you into cloud sandboxes where you lose your whole setup. I also
|
||||
like testing different agents, so locking myself to a single harness or
|
||||
model wasn't an option. Other apps exist but I wasn't happy with their
|
||||
UX, security, or business model.
|
||||
</p>
|
||||
<p>
|
||||
So I built my own. It became good enough that it felt obvious it should
|
||||
exist for others too.
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -251,7 +286,7 @@ function CodeBlock({ children }: { children: React.ReactNode }) {
|
||||
function FAQ() {
|
||||
return (
|
||||
<div className="pt-12 space-y-6">
|
||||
<h2 className="text-2xl font-medium font-serif">FAQ</h2>
|
||||
<h2 className="text-2xl font-medium">FAQ</h2>
|
||||
<div className="space-y-6">
|
||||
<FAQItem question="Is this free?">
|
||||
Paseo is free and open source. It wraps CLI tools like Claude Code and
|
||||
@@ -270,35 +305,7 @@ function FAQ() {
|
||||
</FAQItem>
|
||||
<FAQItem question="What's the business model?">
|
||||
There isn't one. The app and server are free and open source, and
|
||||
that's not changing. I built this for myself. If I find a way to
|
||||
sustain it that benefits everyone, I'll consider it.
|
||||
</FAQItem>
|
||||
<FAQItem question="Why did you build this?">
|
||||
<p>
|
||||
I've been using Claude Code since launch. Early on I started SSHing
|
||||
into Tmux from Termux on Android so I could check on agents during
|
||||
my long walks. It worked, but the UX was rough. Dictation was bad,
|
||||
the keyboard was awkward, and the{' '}
|
||||
<a
|
||||
href="https://github.com/anthropics/claude-code/issues/826"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer nofollow"
|
||||
className="underline hover:text-white/80"
|
||||
>
|
||||
infamous scroll bug
|
||||
</a>{' '}
|
||||
meant starting over constantly.
|
||||
</p>
|
||||
<p>
|
||||
Anthropic and OpenAI added coding agents to their mobile apps, but
|
||||
they force you into cloud sandboxes where you lose your whole setup.
|
||||
Other apps exist but I wasn't happy with their UX, security, or
|
||||
business model.
|
||||
</p>
|
||||
<p>
|
||||
So I built my own. It became good enough that it felt obvious it
|
||||
should exist for others too.
|
||||
</p>
|
||||
that's not changing. I built this for myself.
|
||||
</FAQItem>
|
||||
<FAQItem question="Isn't this just more screen time?">
|
||||
I won't pretend this can't be misused. But for me it means less time
|
||||
@@ -334,23 +341,3 @@ function FAQItem({
|
||||
)
|
||||
}
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<footer className="mt-24 text-sm text-muted-foreground">
|
||||
<div>
|
||||
<a href="/docs" className="hover:text-foreground transition-colors">
|
||||
docs
|
||||
</a>
|
||||
<span className="mx-2">·</span>
|
||||
<a
|
||||
href="https://github.com/moboudra/paseo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground transition-colors"
|
||||
>
|
||||
github
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user