Polish Foundry desktop UI: billing redesign, sidebar hover menu, org switching fix

- Redesign billing page with task-hours pricing model (Free: 8h, Pro: 200h/seat)
- Add bulk hour purchase packages and Stripe payment management
- Remove Usage nav section, add upgrade CTA in Members for free plan
- Fix gear icon to open menu on hover with debounced timers
- Fix org switching in workspace flyout (portal outside-click detection)
- Fix tab strip padding when sidebar is collapsed
- Update website components and Tauri config

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Nicholas Kissel 2026-03-11 19:34:25 -07:00
parent f6656a90af
commit ed6e6f6fa5
24 changed files with 1746 additions and 1028 deletions

View file

@ -105,7 +105,7 @@ export function DownloadFoundry() {
</button>
{showDropdown && (
<div className="absolute left-1/2 top-full mt-2 -translate-x-1/2 rounded-lg border border-white/10 bg-zinc-900 p-2 shadow-xl">
<div className="absolute left-1/2 top-full mt-2 -translate-x-1/2 rounded-lg border border-white/10 bg-[#0f0f11] p-2 shadow-xl">
{secondary.map((p) => (
<a
key={p.arch}

View file

@ -36,7 +36,7 @@ export function FeatureGrid() {
className="grid gap-4 md:grid-cols-2 lg:grid-cols-4"
>
{/* Universal Agent API - Span full width */}
<div className="group col-span-full flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group col-span-full flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-orange-400">
<Workflow className="h-4 w-4" />
@ -49,7 +49,7 @@ export function FeatureGrid() {
</div>
{/* Streaming Events */}
<div className="group flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-green-400">
<Server className="h-4 w-4" />
@ -62,7 +62,7 @@ export function FeatureGrid() {
</div>
{/* Universal Schema */}
<div className="group flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-purple-400">
<Database className="h-4 w-4" />
@ -75,7 +75,7 @@ export function FeatureGrid() {
</div>
{/* Runs Inside Any Sandbox */}
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-blue-400">
<Globe className="h-4 w-4" />
@ -88,7 +88,7 @@ export function FeatureGrid() {
</div>
{/* Session Management */}
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-amber-400">
<Download className="h-4 w-4" />
@ -101,7 +101,7 @@ export function FeatureGrid() {
</div>
{/* OpenCode SDK & UI Support */}
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group lg:col-span-2 flex flex-col gap-4 rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="flex items-center gap-3">
<div className="text-zinc-500 transition-colors group-hover:text-pink-400">
<Plug className="h-4 w-4" />

View file

@ -50,7 +50,7 @@ const footer = {
export function Footer() {
return (
<footer className="border-t border-white/10 bg-black">
<footer className="border-t border-white/10 bg-[#09090b]">
<div className="mx-auto max-w-6xl px-6 py-16 lg:py-20">
<div className="xl:grid xl:grid-cols-12 xl:gap-16">
{/* Logo & Social */}

View file

@ -126,7 +126,7 @@ export function GetStarted() {
className="grid grid-cols-1 gap-4 md:grid-cols-3"
>
{/* Option 1: SDK */}
<div className="group flex flex-col rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group flex flex-col rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="mb-4 flex items-center gap-3">
<div className="text-zinc-500">
<Code className="h-4 w-4" />
@ -142,7 +142,7 @@ export function GetStarted() {
</p>
<div className="flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-black/50 flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-[#0c0c0e] flex-1 flex flex-col">
<div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-3 py-2">
<span className="text-[10px] font-medium text-zinc-500">example.ts</span>
<CopyButton text={sdkCodeRaw} />
@ -153,7 +153,7 @@ export function GetStarted() {
</div>
{/* Option 2: HTTP API */}
<div className="group flex flex-col rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group flex flex-col rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="mb-4 flex items-center gap-3">
<div className="text-zinc-500">
<Server className="h-4 w-4" />
@ -169,7 +169,7 @@ export function GetStarted() {
</p>
<div className="flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-black/50 flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-[#0c0c0e] flex-1 flex flex-col">
<div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-3 py-2">
<span className="text-[10px] font-medium text-zinc-500">terminal</span>
<CopyButton text={sandboxCommand} />
@ -190,7 +190,7 @@ export function GetStarted() {
</div>
{/* Option 3: Open Source */}
<div className="group flex flex-col rounded-2xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="group flex flex-col rounded-xl border border-white/10 bg-white/[0.02] p-6 transition-colors hover:border-white/20">
<div className="mb-4 flex items-center gap-3">
<div className="text-zinc-500">
<GitBranch className="h-4 w-4" />
@ -206,7 +206,7 @@ export function GetStarted() {
</p>
<div className="flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-black/50 flex-1 flex flex-col">
<div className="overflow-hidden rounded-lg border border-white/10 bg-[#0c0c0e] flex-1 flex flex-col">
<div className="flex items-center justify-between border-b border-white/10 bg-white/5 px-3 py-2">
<span className="text-[10px] font-medium text-zinc-500">terminal</span>
<CopyButton text={sourceCommands} />

View file

@ -23,7 +23,7 @@ function UniversalAPIDiagram() {
}, []);
return (
<div className="relative w-full aspect-[4/3] sm:aspect-[16/9] bg-[#050505] rounded-2xl border border-white/10 overflow-hidden flex items-center justify-center shadow-2xl">
<div className="relative w-full aspect-[4/3] sm:aspect-[16/9] bg-[#0c0c0e] rounded-xl border border-white/10 overflow-hidden flex items-center justify-center shadow-2xl">
{/* Background Dots - color changes with active adapter */}
<div
className="absolute inset-0 opacity-[0.15] pointer-events-none transition-all duration-1000"
@ -46,7 +46,7 @@ function UniversalAPIDiagram() {
{/* YOUR APP NODE - Glass dark effect with backdrop blur */}
<foreignObject x="60" y="175" width="180" height="100">
<div className="w-full h-full rounded-2xl border border-white/10 bg-black/40 backdrop-blur-md flex items-center justify-center">
<div className="w-full h-full rounded-xl border border-white/10 bg-[#09090b]/60 backdrop-blur-md flex items-center justify-center">
<span className="text-white text-xl font-bold">Your App</span>
</div>
</foreignObject>
@ -69,7 +69,7 @@ function UniversalAPIDiagram() {
{/* SANDBOX BOUNDARY - Glass dark effect with backdrop blur */}
<foreignObject x="360" y="45" width="410" height="360">
<div className="w-full h-full rounded-3xl border border-white/10 bg-black/40 backdrop-blur-md">
<div className="w-full h-full rounded-xl border border-white/10 bg-[#09090b]/60 backdrop-blur-md">
<div className="text-white text-sm font-extrabold tracking-[0.2em] text-center pt-4">SANDBOX</div>
</div>
</foreignObject>
@ -228,7 +228,7 @@ export function Hero() {
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
className="mb-6 text-3xl font-medium leading-[1.1] tracking-tight text-white md:text-5xl"
className="mb-6 text-3xl font-semibold leading-[1.1] tracking-tight text-white md:text-5xl"
>
Run Coding Agents in Sandboxes.
<br />

View file

@ -32,7 +32,7 @@ export function Inspector() {
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
transition={{ duration: 0.5, delay: 0.2 }}
className="overflow-hidden rounded-2xl border border-white/10"
className="overflow-hidden rounded-xl border border-white/10"
>
<img src="/images/inspector.png" alt="Sandbox Agent Inspector" className="w-full" />
</motion.div>

View file

@ -4,14 +4,14 @@ const integrations = ["Daytona", "E2B", "AI SDK", "Anthropic", "OpenAI", "Docker
export function Integrations() {
return (
<section id="integrations" className="py-24 bg-zinc-900/20 border-t border-white/5 relative overflow-hidden">
<section id="integrations" className="py-24 bg-[#0f0f11]/50 border-t border-white/5 relative overflow-hidden">
<div className="max-w-4xl mx-auto px-6 text-center">
<h2 className="text-3xl font-bold text-white mb-6">Works with your stack</h2>
<h2 className="text-3xl font-semibold text-white mb-6">Works with your stack</h2>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{integrations.map((item) => (
<div
key={item}
className="h-16 flex items-center justify-center rounded-xl border border-white/5 bg-zinc-900/50 text-zinc-300 font-mono text-sm hover:border-accent/40 hover:text-accent transition-all cursor-default"
className="h-16 flex items-center justify-center rounded-xl border border-white/5 bg-white/[0.02] text-zinc-300 font-mono text-sm hover:border-accent/40 hover:text-accent transition-all cursor-default"
>
{item}
</div>

View file

@ -6,7 +6,7 @@ import { GitHubStars } from "./GitHubStars";
function NavItem({ href, children }: { href: string; children: React.ReactNode }) {
return (
<a href={href} className="px-3 py-2 text-sm font-medium text-zinc-400 transition-colors duration-200 hover:text-white">
<a href={href} className="px-3 py-2 text-sm font-normal text-zinc-400 transition-colors duration-200 hover:text-white">
{children}
</a>
);
@ -28,19 +28,19 @@ export function Navigation() {
return (
<div className="fixed top-0 z-50 w-full max-w-[1200px] md:left-1/2 md:top-4 md:-translate-x-1/2 md:px-8">
<div
className={`relative before:pointer-events-none before:absolute before:inset-[-1px] before:z-20 before:hidden before:rounded-2xl before:border before:content-[''] before:transition-colors before:duration-300 before:ease-in-out md:before:block ${
className={`relative before:pointer-events-none before:absolute before:inset-[-1px] before:z-20 before:hidden before:rounded-xl before:border before:content-[''] before:transition-colors before:duration-300 before:ease-in-out md:before:block ${
isScrolled ? "before:border-white/10" : "before:border-transparent"
}`}
>
{/* Background with blur */}
<div
className={`absolute inset-0 -z-[1] hidden overflow-hidden rounded-2xl transition-all duration-300 ease-in-out md:block ${
isScrolled ? "bg-black/80 backdrop-blur-lg" : "bg-transparent backdrop-blur-none"
className={`absolute inset-0 -z-[1] hidden overflow-hidden rounded-xl transition-all duration-300 ease-in-out md:block ${
isScrolled ? "bg-[#09090b]/80 backdrop-blur-lg" : "bg-transparent backdrop-blur-none"
}`}
/>
<header
className={`bg-black/60 border-b-transparent sticky top-0 z-10 flex flex-col items-center border-b backdrop-blur-md pt-2 pb-2 md:static md:bg-transparent md:rounded-2xl md:max-w-[1200px] md:border-transparent md:backdrop-blur-none transition-all hover:opacity-100 ${
className={`bg-[#09090b]/60 border-b-transparent sticky top-0 z-10 flex flex-col items-center border-b backdrop-blur-md pt-2 pb-2 md:static md:bg-transparent md:rounded-xl md:max-w-[1200px] md:border-transparent md:backdrop-blur-none transition-all hover:opacity-100 ${
isScrolled ? "opacity-100" : "opacity-80"
}`}
>
@ -91,7 +91,7 @@ export function Navigation() {
{/* Mobile menu */}
{mobileMenuOpen && (
<div className="md:hidden border border-white/10 bg-black/95 backdrop-blur-lg rounded-2xl mt-2 mx-2 shadow-xl">
<div className="md:hidden border border-white/10 bg-[#09090b]/95 backdrop-blur-lg rounded-xl mt-2 mx-2 shadow-xl">
<div className="px-4 py-4 space-y-1">
<a
href="/docs"

View file

@ -26,18 +26,18 @@ const problems = [
export function ProblemsSolved() {
return (
<section id="features" className="py-24 bg-zinc-950 border-y border-white/5">
<section id="features" className="py-24 bg-[#0f0f11] border-y border-white/5">
<div className="max-w-7xl mx-auto px-6">
<div className="text-center mb-16">
<h2 className="text-3xl font-bold text-white mb-4">Why Coding Agent SDK?</h2>
<h2 className="text-3xl font-semibold text-white mb-4">Why Coding Agent SDK?</h2>
<p className="text-zinc-400 max-w-xl mx-auto">Solving the three fundamental friction points of agentic software development.</p>
</div>
<div className="grid md:grid-cols-3 gap-8">
{problems.map((item, idx) => (
<div key={idx} className="group p-8 rounded-2xl bg-zinc-900/40 border border-white/5 hover:border-accent/30 transition-all duration-300">
<div key={idx} className="group p-8 rounded-xl bg-white/[0.02] border border-white/5 hover:border-accent/30 transition-all duration-300">
<FeatureIcon icon={item.icon} color={item.color} />
<h3 className="text-xl font-bold text-white mb-3">{item.title}</h3>
<h3 className="text-xl font-semibold text-white mb-3">{item.title}</h3>
<p className="text-zinc-400 text-sm leading-relaxed">{item.desc}</p>
</div>
))}

View file

@ -10,11 +10,11 @@ interface ButtonProps {
}
export function Button({ children, variant = "primary", size = "md", href, onClick, className = "" }: ButtonProps) {
const baseStyles = "inline-flex items-center justify-center font-bold rounded-lg transition-all";
const baseStyles = "inline-flex items-center justify-center font-medium rounded-lg transition-all";
const variants = {
primary: "bg-white text-black hover:bg-zinc-200",
secondary: "bg-zinc-900 border border-white/10 text-white hover:bg-zinc-800",
secondary: "bg-[#0f0f11] border border-white/10 text-white hover:bg-white/[0.06]",
ghost: "text-zinc-400 hover:text-white",
};