fix(website): simplify landing page and improve UX

This commit is contained in:
Mohamed Boudra
2026-02-05 14:00:52 +07:00
parent bac6277012
commit 0df416b842
+91 -104
View File
@@ -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>
)
}