improved a lot of things

This commit is contained in:
SinachPat
2026-04-29 05:00:17 +01:00
parent 957bb9e0e7
commit 6624a63d3b
15 changed files with 197 additions and 151 deletions
+6 -5
View File
@@ -24,9 +24,10 @@ export default function GlobalError({
padding: 24, padding: 24,
}}> }}>
<div style={{ <div style={{
background: '#FFFFFF', border: '1px solid rgba(220,38,38,0.15)', background: 'var(--card-bg)', border: '1px solid rgba(220,38,38,0.15)',
borderRadius: 16, padding: '44px 48px', maxWidth: 480, width: '100%', borderRadius: 16, padding: '44px 48px', maxWidth: 480, width: '100%',
boxShadow: '0 4px 24px rgba(0,0,0,0.06)', textAlign: 'center', boxShadow: '0 4px 24px rgba(0,0,0,0.06)', textAlign: 'center',
transition: 'background 0.2s',
}}> }}>
<div style={{ <div style={{
width: 48, height: 48, borderRadius: 12, width: 48, height: 48, borderRadius: 12,
@@ -39,10 +40,10 @@ export default function GlobalError({
<circle cx="10" cy="10" r="8.5" stroke="#DC2626" strokeWidth="1.5"/> <circle cx="10" cy="10" r="8.5" stroke="#DC2626" strokeWidth="1.5"/>
</svg> </svg>
</div> </div>
<h1 style={{ fontSize: '1.125rem', fontWeight: 700, color: '#0A0A0A', margin: '0 0 8px', letterSpacing: '-0.02em' }}> <h1 style={{ fontSize: '1.125rem', fontWeight: 700, color: 'var(--card-text)', margin: '0 0 8px', letterSpacing: '-0.02em' }}>
Something went wrong Something went wrong
</h1> </h1>
<p style={{ fontSize: '0.875rem', color: '#71717A', margin: '0 0 28px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', margin: '0 0 28px', lineHeight: 1.6 }}>
{error.message || 'An unexpected error occurred.'} {error.message || 'An unexpected error occurred.'}
</p> </p>
<div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}> <div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
@@ -51,7 +52,7 @@ export default function GlobalError({
style={{ style={{
padding: '9px 20px', borderRadius: 8, padding: '9px 20px', borderRadius: 8,
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
background: '#0A0A0A', color: '#FFFFFF', border: 'none', background: 'var(--btn-bg)', color: 'var(--btn-fg)', border: 'none',
cursor: 'pointer', fontFamily: 'inherit', cursor: 'pointer', fontFamily: 'inherit',
}} }}
> >
@@ -62,7 +63,7 @@ export default function GlobalError({
style={{ style={{
padding: '9px 20px', borderRadius: 8, padding: '9px 20px', borderRadius: 8,
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
background: '#F4F4F5', color: '#3F3F46', background: 'var(--card-subtle)', color: 'var(--btn-idle-fg)',
border: 'none', textDecoration: 'none', border: 'none', textDecoration: 'none',
display: 'inline-flex', alignItems: 'center', display: 'inline-flex', alignItems: 'center',
}} }}
+40 -4
View File
@@ -20,13 +20,49 @@ html, body {
enough for all shell pages to respond. */ enough for all shell pages to respond. */
:root { :root {
--page-bg: #FAFAFA; --page-bg: #FAFAFA;
--page-text: #0A0A0A; --page-text: #0A0A0A;
/* Cards / sections */
--card-bg: #FFFFFF;
--card-border: rgba(0,0,0,0.08);
--card-text: #0A0A0A;
--card-muted: #71717A;
--card-subtle: #F4F4F5;
--card-icon-bg: #0A0A0A;
--card-icon-fg: #FFFFFF;
/* Inputs / selects */
--input-bg: #F8F8F8;
--input-border: rgba(0,0,0,0.12);
--input-text: #0A0A0A;
/* Buttons */
--btn-bg: #0A0A0A;
--btn-fg: #FFFFFF;
--btn-idle-bg: #FFFFFF;
--btn-idle-fg: #52525B;
--btn-idle-border: rgba(0,0,0,0.12);
} }
[data-theme="dark"] { [data-theme="dark"] {
--page-bg: #0C0C10; --page-bg: #0C0C10;
--page-text: #FAFAFA; --page-text: #FAFAFA;
/* Cards / sections */
--card-bg: #16161C;
--card-border: rgba(255,255,255,0.07);
--card-text: rgba(255,255,255,0.88);
--card-muted: rgba(255,255,255,0.42);
--card-subtle: rgba(255,255,255,0.06);
--card-icon-bg: rgba(255,255,255,0.10);
--card-icon-fg: rgba(255,255,255,0.88);
/* Inputs / selects */
--input-bg: rgba(255,255,255,0.05);
--input-border: rgba(255,255,255,0.11);
--input-text: rgba(255,255,255,0.88);
/* Buttons */
--btn-bg: rgba(255,255,255,0.92);
--btn-fg: #0A0A0A;
--btn-idle-bg: rgba(255,255,255,0.05);
--btn-idle-fg: rgba(255,255,255,0.55);
--btn-idle-border: rgba(255,255,255,0.12);
} }
body { body {
+12 -12
View File
@@ -54,15 +54,15 @@ export default function OnboardingPage() {
padding: '24px', padding: '24px',
}}> }}>
{/* Logo */} {/* Logo */}
<div style={{ marginBottom: 40, fontSize: '1.125rem', fontWeight: 700, letterSpacing: '-0.02em', color: '#0A0A0A' }}> <div style={{ marginBottom: 40, fontSize: '1.125rem', fontWeight: 700, letterSpacing: '-0.02em', color: 'var(--page-text)' }}>
Origin<span style={{ color: '#0066FF' }}>main</span> Origin<span style={{ color: '#0066FF' }}>main</span>
</div> </div>
{/* Card */} {/* Card */}
<div style={{ <div style={{
background: '#FFFFFF', border: '1px solid rgba(0,0,0,0.07)', background: 'var(--card-bg)', border: '1px solid var(--card-border)',
borderRadius: 20, padding: '44px 48px', maxWidth: 460, width: '100%', borderRadius: 20, padding: '44px 48px', maxWidth: 460, width: '100%',
boxShadow: '0 4px 24px rgba(0,0,0,0.06)', boxShadow: '0 4px 24px rgba(0,0,0,0.06)', transition: 'background 0.2s',
}}> }}>
<div style={{ <div style={{
width: 52, height: 52, borderRadius: 13, width: 52, height: 52, borderRadius: 13,
@@ -77,15 +77,15 @@ export default function OnboardingPage() {
</svg> </svg>
</div> </div>
<h1 style={{ fontSize: '1.375rem', fontWeight: 700, letterSpacing: '-0.03em', color: '#0A0A0A', margin: '0 0 8px' }}> <h1 style={{ fontSize: '1.375rem', fontWeight: 700, letterSpacing: '-0.03em', color: 'var(--card-text)', margin: '0 0 8px' }}>
Welcome, {firstName}! Welcome, {firstName}!
</h1> </h1>
<p style={{ fontSize: '0.9rem', color: '#71717A', lineHeight: 1.6, margin: '0 0 28px' }}> <p style={{ fontSize: '0.9rem', color: 'var(--card-muted)', lineHeight: 1.6, margin: '0 0 28px' }}>
Let's create your workspace. A workspace holds your projects and team — usually named after your company or product. Let's create your workspace. A workspace holds your projects and team — usually named after your company or product.
</p> </p>
<form onSubmit={handleCreate}> <form onSubmit={handleCreate}>
<label style={{ display: 'block', fontSize: '0.8125rem', fontWeight: 600, color: '#3F3F46', marginBottom: 6 }}> <label style={{ display: 'block', fontSize: '0.8125rem', fontWeight: 600, color: 'var(--card-text)', marginBottom: 6 }}>
Workspace name Workspace name
</label> </label>
<input <input
@@ -97,14 +97,14 @@ export default function OnboardingPage() {
style={{ style={{
width: '100%', boxSizing: 'border-box', width: '100%', boxSizing: 'border-box',
padding: '11px 13px', fontSize: '0.9375rem', padding: '11px 13px', fontSize: '0.9375rem',
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 9, border: '1px solid var(--input-border)', borderRadius: 9,
color: '#0A0A0A', background: '#FFFFFF', color: 'var(--input-text)', background: 'var(--input-bg)',
fontFamily: 'inherit', fontFamily: 'inherit',
}} }}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
/> />
<p style={{ margin: '6px 0 0', fontSize: '0.75rem', color: '#A1A1AA' }}> <p style={{ margin: '6px 0 0', fontSize: '0.75rem', color: 'var(--card-muted)' }}>
Leave blank to use "{defaultName}" Leave blank to use "{defaultName}"
</p> </p>
@@ -117,8 +117,8 @@ export default function OnboardingPage() {
marginTop: 24, width: '100%', marginTop: 24, width: '100%',
padding: '12px', borderRadius: 9, padding: '12px', borderRadius: 9,
fontSize: '0.9375rem', fontWeight: 600, fontSize: '0.9375rem', fontWeight: 600,
background: loading ? '#D4D4D8' : '#0A0A0A', background: loading ? 'var(--card-subtle)' : 'var(--btn-bg)',
color: '#FFFFFF', border: 'none', color: loading ? 'var(--card-muted)' : 'var(--btn-fg)', border: 'none',
cursor: loading ? 'default' : 'pointer', cursor: loading ? 'default' : 'pointer',
fontFamily: 'inherit', letterSpacing: '-0.01em', fontFamily: 'inherit', letterSpacing: '-0.01em',
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
+11 -10
View File
@@ -57,10 +57,10 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
{/* Title row */} {/* Title row */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 32 }}> <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 32 }}>
<div> <div>
<h1 style={{ fontSize: '1.5rem', fontWeight: 700, letterSpacing: '-0.03em', color: '#0A0A0A', margin: 0 }}> <h1 style={{ fontSize: '1.5rem', fontWeight: 700, letterSpacing: '-0.03em', color: 'var(--page-text)', margin: 0 }}>
Projects Projects
</h1> </h1>
<p style={{ margin: '4px 0 0', fontSize: '0.875rem', color: '#71717A' }}> <p style={{ margin: '4px 0 0', fontSize: '0.875rem', color: 'var(--card-muted)' }}>
{projects.length === 0 {projects.length === 0
? 'No projects yet — connect your first app to get started' ? 'No projects yet — connect your first app to get started'
: `${projects.length} project${projects.length !== 1 ? 's' : ''}`} : `${projects.length} project${projects.length !== 1 ? 's' : ''}`}
@@ -69,10 +69,10 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
<div style={{ display: 'flex', gap: 10 }}> <div style={{ display: 'flex', gap: 10 }}>
<Link href={`/workspace/${wid}/plugins`} style={{ <Link href={`/workspace/${wid}/plugins`} style={{
display: 'inline-flex', alignItems: 'center', gap: 6, display: 'inline-flex', alignItems: 'center', gap: 6,
background: 'transparent', color: '#71717A', background: 'transparent', color: 'var(--card-muted)',
fontSize: '0.875rem', fontWeight: 500, fontSize: '0.875rem', fontWeight: 500,
padding: '9px 16px', borderRadius: 9, padding: '9px 16px', borderRadius: 9,
textDecoration: 'none', border: '1px solid rgba(0,0,0,0.1)', textDecoration: 'none', border: '1px solid var(--card-border)',
}}> }}>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none"> <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
<path d="M12 2a2 2 0 0 1 2 2v1h3a1 1 0 0 1 1 1v3h1a2 2 0 0 1 0 4h-1v3a1 1 0 0 1-1 1h-3v1a2 2 0 0 1-4 0v-1H7a1 1 0 0 1-1-1v-3H5a2 2 0 0 1 0-4h1V6a1 1 0 0 1 1-1h3V4a2 2 0 0 1 2-2z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/> <path d="M12 2a2 2 0 0 1 2 2v1h3a1 1 0 0 1 1 1v3h1a2 2 0 0 1 0 4h-1v3a1 1 0 0 1-1 1h-3v1a2 2 0 0 1-4 0v-1H7a1 1 0 0 1-1-1v-3H5a2 2 0 0 1 0-4h1V6a1 1 0 0 1 1-1h3V4a2 2 0 0 1 2-2z" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
@@ -81,10 +81,10 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
</Link> </Link>
<Link href={`/workspace/${wid}/settings`} style={{ <Link href={`/workspace/${wid}/settings`} style={{
display: 'inline-flex', alignItems: 'center', gap: 6, display: 'inline-flex', alignItems: 'center', gap: 6,
background: 'transparent', color: '#71717A', background: 'transparent', color: 'var(--card-muted)',
fontSize: '0.875rem', fontWeight: 500, fontSize: '0.875rem', fontWeight: 500,
padding: '9px 16px', borderRadius: 9, padding: '9px 16px', borderRadius: 9,
textDecoration: 'none', border: '1px solid rgba(0,0,0,0.1)', textDecoration: 'none', border: '1px solid var(--card-border)',
}}> }}>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"> <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<circle cx="7" cy="7" r="2" stroke="currentColor" strokeWidth="1.4"/> <circle cx="7" cy="7" r="2" stroke="currentColor" strokeWidth="1.4"/>
@@ -94,7 +94,7 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
</Link> </Link>
<Link href={`/workspace/${wid}/project/new`} style={{ <Link href={`/workspace/${wid}/project/new`} style={{
display: 'inline-flex', alignItems: 'center', gap: 6, display: 'inline-flex', alignItems: 'center', gap: 6,
background: '#0A0A0A', color: '#FFFFFF', background: 'var(--btn-bg)', color: 'var(--btn-fg)',
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
padding: '9px 18px', borderRadius: 9, padding: '9px 18px', borderRadius: 9,
textDecoration: 'none', letterSpacing: '-0.01em', textDecoration: 'none', letterSpacing: '-0.01em',
@@ -110,8 +110,9 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
{/* Empty state */} {/* Empty state */}
{projects.length === 0 && ( {projects.length === 0 && (
<div style={{ <div style={{
background: '#FFFFFF', border: '1px dashed rgba(0,0,0,0.12)', background: 'var(--card-bg)', border: '1px dashed var(--card-border)',
borderRadius: 16, padding: '56px 40px', textAlign: 'center', borderRadius: 16, padding: '56px 40px', textAlign: 'center',
transition: 'background 0.2s',
}}> }}>
<div style={{ <div style={{
width: 52, height: 52, borderRadius: 14, width: 52, height: 52, borderRadius: 14,
@@ -123,10 +124,10 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
<path d="M7 9.5l2.5 2.5L15 7" stroke="#0066FF" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/> <path d="M7 9.5l2.5 2.5L15 7" stroke="#0066FF" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/>
</svg> </svg>
</div> </div>
<h3 style={{ fontSize: '1rem', fontWeight: 600, color: '#0A0A0A', margin: '0 0 8px' }}> <h3 style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 8px' }}>
Connect your first app Connect your first app
</h3> </h3>
<p style={{ fontSize: '0.875rem', color: '#71717A', margin: '0 0 24px', maxWidth: 360, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.6 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', margin: '0 0 24px', maxWidth: 360, marginLeft: 'auto', marginRight: 'auto', lineHeight: 1.6 }}>
A project connects to your running application local or staging so you can inspect components and ship intent-level diffs. A project connects to your running application local or staging so you can inspect components and ship intent-level diffs.
</p> </p>
<Link href={`/workspace/${wid}/project/new`} style={{ <Link href={`/workspace/${wid}/project/new`} style={{
@@ -39,25 +39,25 @@ export default async function WorkspacePluginsPage({ params }: { params: Promise
<div style={{ maxWidth: 760, margin: '0 auto', padding: '48px 24px' }}> <div style={{ maxWidth: 760, margin: '0 auto', padding: '48px 24px' }}>
{/* Breadcrumb */} {/* Breadcrumb */}
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 32, fontSize: '0.8125rem', color: '#71717A' }}> <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 32, fontSize: '0.8125rem', color: 'var(--card-muted)' }}>
<Link href="/workspaces" style={{ color: '#71717A', textDecoration: 'none' }}>Workspaces</Link> <Link href="/workspaces" style={{ color: 'var(--card-muted)', textDecoration: 'none' }}>Workspaces</Link>
<span>/</span> <span>/</span>
<Link href={`/workspace/${wid}`} style={{ color: '#71717A', textDecoration: 'none' }}>{workspace?.name ?? 'Workspace'}</Link> <Link href={`/workspace/${wid}`} style={{ color: 'var(--card-muted)', textDecoration: 'none' }}>{workspace?.name ?? 'Workspace'}</Link>
<span>/</span> <span>/</span>
<span style={{ color: '#09090B' }}>Plugins</span> <span style={{ color: 'var(--page-text)' }}>Plugins</span>
</div> </div>
<h1 style={{ fontSize: '1.5rem', fontWeight: 700, letterSpacing: '-0.025em', color: '#09090B', margin: '0 0 8px' }}> <h1 style={{ fontSize: '1.5rem', fontWeight: 700, letterSpacing: '-0.025em', color: 'var(--page-text)', margin: '0 0 8px' }}>
Plugins Plugins
</h1> </h1>
<p style={{ fontSize: '0.9375rem', color: '#52525B', margin: '0 0 40px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.9375rem', color: 'var(--card-muted)', margin: '0 0 40px', lineHeight: 1.6 }}>
Extend Originmain with custom completion zones, ingestion connectors, and design tools. Extend Originmain with custom completion zones, ingestion connectors, and design tools.
</p> </p>
{/* Coming soon card */} {/* Coming soon card */}
<div style={{ <div style={{
background: '#FFFFFF', border: '1px solid rgba(0,0,0,0.07)', borderRadius: 14, background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 14,
padding: '40px 36px', textAlign: 'center', padding: '40px 36px', textAlign: 'center', transition: 'background 0.2s',
}}> }}>
<div style={{ <div style={{
width: 52, height: 52, borderRadius: 14, width: 52, height: 52, borderRadius: 14,
@@ -71,10 +71,10 @@ export default async function WorkspacePluginsPage({ params }: { params: Promise
</svg> </svg>
</div> </div>
<h2 style={{ fontSize: '1.125rem', fontWeight: 600, color: '#09090B', margin: '0 0 10px', letterSpacing: '-0.015em' }}> <h2 style={{ fontSize: '1.125rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 10px', letterSpacing: '-0.015em' }}>
Plugin marketplace coming in Phase 4 Plugin marketplace coming in Phase 4
</h2> </h2>
<p style={{ fontSize: '0.875rem', color: '#71717A', maxWidth: 480, margin: '0 auto 28px', lineHeight: 1.65 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', maxWidth: 480, margin: '0 auto 28px', lineHeight: 1.65 }}>
The plugin API lets teams register custom AI completion zones, custom webhook ingesters, and design-language extensions all sandboxed and permission-scoped. The plugin API lets teams register custom AI completion zones, custom webhook ingesters, and design-language extensions all sandboxed and permission-scoped.
</p> </p>
@@ -51,40 +51,42 @@ export default async function ProjectSettingsPage({
return ( return (
<div style={{ <div style={{
minHeight: '100dvh', minHeight: '100dvh',
background: '#F5F5F7', background: 'var(--page-bg)',
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif", fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
transition: 'background 0.2s',
}}> }}>
{/* Header */} {/* Header */}
<div style={{ <div style={{
background: '#FFFFFF', background: 'var(--card-bg)',
borderBottom: '1px solid rgba(0,0,0,0.07)', borderBottom: '1px solid var(--card-border)',
padding: '0 32px', padding: '0 32px',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
height: 56, height: 56,
gap: 0, gap: 0,
transition: 'background 0.2s',
}}> }}>
<Link href="/workspaces" style={{ textDecoration: 'none', fontSize: '0.875rem', fontWeight: 700, color: '#0A0A0A', letterSpacing: '-0.01em' }}> <Link href="/workspaces" style={{ textDecoration: 'none', fontSize: '0.875rem', fontWeight: 700, color: 'var(--card-text)', letterSpacing: '-0.01em' }}>
Origin<span style={{ color: '#3385FF' }}>main</span> Origin<span style={{ color: '#3385FF' }}>main</span>
</Link> </Link>
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span> <span style={{ color: 'var(--card-border)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
<Link href={`/workspace/${wid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: '#52525B', fontWeight: 500 }}> <Link href={`/workspace/${wid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: 'var(--card-muted)', fontWeight: 500 }}>
{wsResult.data?.name ?? 'Workspace'} {wsResult.data?.name ?? 'Workspace'}
</Link> </Link>
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span> <span style={{ color: 'var(--card-border)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
<Link href={`/workspace/${wid}/project/${pid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: '#52525B', fontWeight: 500 }}> <Link href={`/workspace/${wid}/project/${pid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: 'var(--card-muted)', fontWeight: 500 }}>
{project.name} {project.name}
</Link> </Link>
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span> <span style={{ color: 'var(--card-border)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
<span style={{ fontSize: '0.875rem', color: '#0A0A0A', fontWeight: 600 }}>Settings</span> <span style={{ fontSize: '0.875rem', color: 'var(--card-text)', fontWeight: 600 }}>Settings</span>
</div> </div>
{/* Content */} {/* Content */}
<div style={{ maxWidth: 640, margin: '0 auto', padding: '40px 24px' }}> <div style={{ maxWidth: 640, margin: '0 auto', padding: '40px 24px' }}>
<h1 style={{ fontSize: '1.375rem', fontWeight: 700, color: '#0A0A0A', margin: '0 0 6px', letterSpacing: '-0.02em' }}> <h1 style={{ fontSize: '1.375rem', fontWeight: 700, color: 'var(--page-text)', margin: '0 0 6px', letterSpacing: '-0.02em' }}>
Project settings Project settings
</h1> </h1>
<p style={{ fontSize: '0.875rem', color: '#71717A', margin: '0 0 32px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', margin: '0 0 32px', lineHeight: 1.6 }}>
Configure your project name, URL, and framework. Configure your project name, URL, and framework.
</p> </p>
@@ -49,15 +49,15 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
const inputStyle = { const inputStyle = {
width: '100%', boxSizing: 'border-box' as const, width: '100%', boxSizing: 'border-box' as const,
padding: '10px 12px', fontSize: '0.9375rem', padding: '10px 12px', fontSize: '0.9375rem',
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 8, border: '1px solid var(--input-border)', borderRadius: 8,
color: '#0A0A0A', background: '#FFFFFF', color: 'var(--input-text)', background: 'var(--input-bg)',
fontFamily: 'inherit', fontFamily: 'inherit',
}; };
const labelStyle = { const labelStyle = {
display: 'block' as const, display: 'block' as const,
fontSize: '0.8125rem', fontWeight: 600 as const, fontSize: '0.8125rem', fontWeight: 600 as const,
color: '#3F3F46', marginBottom: 6, color: 'var(--card-text)', marginBottom: 6,
}; };
return ( return (
@@ -69,11 +69,11 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
]} /> ]} />
<main style={{ maxWidth: 540, margin: '64px auto', padding: '0 24px' }}> <main style={{ maxWidth: 540, margin: '64px auto', padding: '0 24px' }}>
<div style={{ background: '#FFFFFF', border: '1px solid rgba(0,0,0,0.07)', borderRadius: 16, padding: '36px 40px', boxShadow: '0 4px 24px rgba(0,0,0,0.05)' }}> <div style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 16, padding: '36px 40px', boxShadow: '0 4px 24px rgba(0,0,0,0.05)', transition: 'background 0.2s' }}>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: '#0A0A0A', margin: '0 0 6px' }}> <h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: 'var(--card-text)', margin: '0 0 6px' }}>
New project New project
</h1> </h1>
<p style={{ fontSize: '0.875rem', color: '#71717A', margin: '0 0 28px', lineHeight: 1.5 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', margin: '0 0 28px', lineHeight: 1.5 }}>
A project connects to your running app so you can inspect components live, create artboards, and ship intent diffs. A project connects to your running app so you can inspect components live, create artboards, and ship intent diffs.
</p> </p>
@@ -87,7 +87,7 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
placeholder="Dashboard App" placeholder="Dashboard App"
autoFocus style={inputStyle} autoFocus style={inputStyle}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
/> />
</div> </div>
@@ -99,9 +99,9 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
placeholder="http://localhost:3000 or https://staging.myapp.com" placeholder="http://localhost:3000 or https://staging.myapp.com"
style={inputStyle} style={inputStyle}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
/> />
<p style={{ margin: '5px 0 0', fontSize: '0.75rem', color: '#A1A1AA' }}> <p style={{ margin: '5px 0 0', fontSize: '0.75rem', color: 'var(--card-muted)' }}>
The address where your app is running local or remote. The address where your app is running local or remote.
</p> </p>
</div> </div>
@@ -113,7 +113,7 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
value={framework} onChange={e => setFramework(e.target.value)} value={framework} onChange={e => setFramework(e.target.value)}
style={{ ...inputStyle, color: framework ? '#0A0A0A' : '#A1A1AA', cursor: 'pointer' }} style={{ ...inputStyle, color: framework ? '#0A0A0A' : '#A1A1AA', cursor: 'pointer' }}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
> >
<option value="">Select framework (optional)</option> <option value="">Select framework (optional)</option>
{FRAMEWORKS.map(f => <option key={f} value={f.toLowerCase().replace('.', '')}>{f}</option>)} {FRAMEWORKS.map(f => <option key={f} value={f.toLowerCase().replace('.', '')}>{f}</option>)}
@@ -129,7 +129,7 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
rows={3} rows={3}
style={{ ...inputStyle, resize: 'vertical', lineHeight: 1.5 }} style={{ ...inputStyle, resize: 'vertical', lineHeight: 1.5 }}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
/> />
</div> </div>
@@ -140,8 +140,8 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
<div style={{ display: 'flex', gap: 10, marginTop: 4 }}> <div style={{ display: 'flex', gap: 10, marginTop: 4 }}>
<Link href={`/workspace/${wid}`} style={{ <Link href={`/workspace/${wid}`} style={{
flex: 1, textAlign: 'center', padding: '10px', borderRadius: 8, flex: 1, textAlign: 'center', padding: '10px', borderRadius: 8,
fontSize: '0.875rem', fontWeight: 600, color: '#3F3F46', fontSize: '0.875rem', fontWeight: 600, color: 'var(--btn-idle-fg)',
background: '#F4F4F5', textDecoration: 'none', background: 'var(--card-subtle)', textDecoration: 'none',
}}> }}>
Cancel Cancel
</Link> </Link>
@@ -151,8 +151,9 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
style={{ style={{
flex: 2, padding: '10px', borderRadius: 8, flex: 2, padding: '10px', borderRadius: 8,
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
background: name.trim() && !loading ? '#0A0A0A' : '#D4D4D8', background: name.trim() && !loading ? 'var(--btn-bg)' : 'var(--card-subtle)',
color: '#FFFFFF', border: 'none', color: name.trim() && !loading ? 'var(--btn-fg)' : 'var(--card-muted)',
border: 'none',
cursor: name.trim() && !loading ? 'pointer' : 'default', cursor: name.trim() && !loading ? 'pointer' : 'default',
fontFamily: 'inherit', transition: 'background 0.15s', fontFamily: 'inherit', transition: 'background 0.15s',
}} }}
+11 -10
View File
@@ -39,16 +39,16 @@ export default function NewWorkspacePage() {
<AppHeader breadcrumbs={[{ label: 'Workspaces', href: '/workspaces' }, { label: 'New workspace' }]} /> <AppHeader breadcrumbs={[{ label: 'Workspaces', href: '/workspaces' }, { label: 'New workspace' }]} />
<main style={{ maxWidth: 480, margin: '64px auto', padding: '0 24px' }}> <main style={{ maxWidth: 480, margin: '64px auto', padding: '0 24px' }}>
<div style={{ background: '#FFFFFF', border: '1px solid rgba(0,0,0,0.07)', borderRadius: 16, padding: '36px 40px', boxShadow: '0 4px 24px rgba(0,0,0,0.05)' }}> <div style={{ background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 16, padding: '36px 40px', boxShadow: '0 4px 24px rgba(0,0,0,0.05)', transition: 'background 0.2s' }}>
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: '#0A0A0A', margin: '0 0 6px' }}> <h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: 'var(--card-text)', margin: '0 0 6px' }}>
New workspace New workspace
</h1> </h1>
<p style={{ fontSize: '0.875rem', color: '#71717A', margin: '0 0 28px', lineHeight: 1.5 }}> <p style={{ fontSize: '0.875rem', color: 'var(--card-muted)', margin: '0 0 28px', lineHeight: 1.5 }}>
A workspace holds your projects and team. Give it a name usually your company or team name. A workspace holds your projects and team. Give it a name usually your company or team name.
</p> </p>
<form onSubmit={handleCreate}> <form onSubmit={handleCreate}>
<label style={{ display: 'block', fontSize: '0.8125rem', fontWeight: 600, color: '#3F3F46', marginBottom: 6 }}> <label style={{ display: 'block', fontSize: '0.8125rem', fontWeight: 600, color: 'var(--card-text)', marginBottom: 6 }}>
Workspace name Workspace name
</label> </label>
<input <input
@@ -60,12 +60,12 @@ export default function NewWorkspacePage() {
style={{ style={{
width: '100%', boxSizing: 'border-box', width: '100%', boxSizing: 'border-box',
padding: '10px 12px', fontSize: '0.9375rem', padding: '10px 12px', fontSize: '0.9375rem',
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 8, border: '1px solid var(--input-border)', borderRadius: 8,
color: '#0A0A0A', background: '#FFFFFF', color: 'var(--input-text)', background: 'var(--input-bg)',
fontFamily: 'inherit', fontFamily: 'inherit',
}} }}
onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')} onFocus={e => (e.currentTarget.style.borderColor = '#0066FF')}
onBlur={e => (e.currentTarget.style.borderColor = 'rgba(0,0,0,0.12)')} onBlur={e => (e.currentTarget.style.borderColor = 'var(--input-border)')}
/> />
{error && ( {error && (
@@ -76,7 +76,7 @@ export default function NewWorkspacePage() {
<Link href="/workspaces" style={{ <Link href="/workspaces" style={{
flex: 1, textAlign: 'center', flex: 1, textAlign: 'center',
padding: '10px', borderRadius: 8, fontSize: '0.875rem', fontWeight: 600, padding: '10px', borderRadius: 8, fontSize: '0.875rem', fontWeight: 600,
color: '#3F3F46', background: '#F4F4F5', textDecoration: 'none', color: 'var(--btn-idle-fg)', background: 'var(--card-subtle)', textDecoration: 'none',
}}> }}>
Cancel Cancel
</Link> </Link>
@@ -86,8 +86,9 @@ export default function NewWorkspacePage() {
style={{ style={{
flex: 2, padding: '10px', borderRadius: 8, flex: 2, padding: '10px', borderRadius: 8,
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
background: name.trim() && !loading ? '#0A0A0A' : '#D4D4D8', background: name.trim() && !loading ? 'var(--btn-bg)' : 'var(--card-subtle)',
color: '#FFFFFF', border: 'none', cursor: name.trim() && !loading ? 'pointer' : 'default', color: name.trim() && !loading ? 'var(--btn-fg)' : 'var(--card-muted)',
border: 'none', cursor: name.trim() && !loading ? 'pointer' : 'default',
fontFamily: 'inherit', transition: 'background 0.15s', fontFamily: 'inherit', transition: 'background 0.15s',
}} }}
> >
@@ -117,29 +117,30 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
padding: '0 14px', gap: 0, padding: '0 14px', gap: 0,
zIndex: 10, zIndex: 10,
position: 'relative', position: 'relative',
transition: 'background 0.2s, border-color 0.2s',
}}> }}>
{/* Logo */} {/* Logo */}
<Link href="/workspaces" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', marginRight: 4 }}> <Link href="/workspaces" style={{ textDecoration: 'none', display: 'flex', alignItems: 'center', marginRight: 4 }}>
<span style={{ fontSize: '0.75rem', fontWeight: 700, letterSpacing: '-0.01em', color: 'rgba(255,255,255,0.6)' }}> <span style={{ fontSize: '0.75rem', fontWeight: 700, letterSpacing: '-0.01em', color: CT.itemHov }}>
Origin<span style={{ color: '#3385FF' }}>main</span> Origin<span style={{ color: CT.accent }}>main</span>
</span> </span>
</Link> </Link>
<span style={{ color: 'rgba(255,255,255,0.2)', margin: '0 6px', fontSize: '0.75rem' }}>/</span> <span style={{ color: CT.fgDim, margin: '0 6px', fontSize: '0.75rem' }}>/</span>
<Link href="/workspaces" style={{ textDecoration: 'none', fontSize: '0.75rem', color: 'rgba(255,255,255,0.4)', fontWeight: 500 }}> <Link href="/workspaces" style={{ textDecoration: 'none', fontSize: '0.75rem', color: CT.item, fontWeight: 500 }}>
Workspaces Workspaces
</Link> </Link>
<span style={{ color: 'rgba(255,255,255,0.2)', margin: '0 6px', fontSize: '0.75rem' }}>/</span> <span style={{ color: CT.fgDim, margin: '0 6px', fontSize: '0.75rem' }}>/</span>
<Link href={`/workspace/${workspaceId}`} style={{ textDecoration: 'none', fontSize: '0.75rem', color: 'rgba(255,255,255,0.4)', fontWeight: 500 }}> <Link href={`/workspace/${workspaceId}`} style={{ textDecoration: 'none', fontSize: '0.75rem', color: CT.item, fontWeight: 500 }}>
{workspaceName ?? 'Workspace'} {workspaceName ?? 'Workspace'}
</Link> </Link>
<span style={{ color: 'rgba(255,255,255,0.2)', margin: '0 6px', fontSize: '0.75rem' }}>/</span> <span style={{ color: CT.fgDim, margin: '0 6px', fontSize: '0.75rem' }}>/</span>
<span style={{ fontSize: '0.75rem', color: 'rgba(255,255,255,0.75)', fontWeight: 600 }}> <span style={{ fontSize: '0.75rem', color: CT.fg, fontWeight: 600 }}>
{projectName ?? 'Canvas'} {projectName ?? 'Canvas'}
</span> </span>
@@ -152,11 +153,11 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
marginLeft: 8, marginLeft: 8,
display: 'flex', alignItems: 'center', display: 'flex', alignItems: 'center',
textDecoration: 'none', textDecoration: 'none',
color: 'rgba(255,255,255,0.25)', color: CT.dim,
transition: 'color 0.12s', transition: 'color 0.12s',
}} }}
onMouseEnter={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.65)')} onMouseEnter={e => (e.currentTarget.style.color = CT.itemHov)}
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.25)')} onMouseLeave={e => (e.currentTarget.style.color = CT.dim)}
> >
<svg width="12" height="12" viewBox="0 0 12 12" fill="none"> <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
<path d="M6 7.5A1.5 1.5 0 1 0 6 4.5 1.5 1.5 0 0 0 6 7.5Z" stroke="currentColor" strokeWidth="1" strokeLinecap="round"/> <path d="M6 7.5A1.5 1.5 0 1 0 6 4.5 1.5 1.5 0 0 0 6 7.5Z" stroke="currentColor" strokeWidth="1" strokeLinecap="round"/>
@@ -173,13 +174,13 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
title={`Switch to ${themeMode === 'dark' ? 'light' : 'dark'} mode`} title={`Switch to ${themeMode === 'dark' ? 'light' : 'dark'} mode`}
style={{ style={{
background: 'none', border: 'none', cursor: 'pointer', background: 'none', border: 'none', cursor: 'pointer',
color: 'rgba(255,255,255,0.35)', padding: '4px 6px', color: CT.fgMuted, padding: '4px 6px',
display: 'flex', alignItems: 'center', display: 'flex', alignItems: 'center',
transition: 'color 0.12s', transition: 'color 0.12s',
fontSize: 13, fontSize: 13,
}} }}
onMouseEnter={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.75)')} onMouseEnter={e => (e.currentTarget.style.color = CT.itemHov)}
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.35)')} onMouseLeave={e => (e.currentTarget.style.color = CT.fgMuted)}
> >
{themeMode === 'dark' ? ( {themeMode === 'dark' ? (
/* Sun icon */ /* Sun icon */
@@ -53,19 +53,20 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
return ( return (
<div <div
style={{ style={{
background: '#FFFFFF', background: 'var(--card-bg)',
border: '1px solid #E4E4E7', border: '1px solid var(--card-border)',
borderRadius: 12, borderRadius: 12,
padding: '24px 28px', padding: '24px 28px',
marginTop: 32, marginTop: 32,
transition: 'background 0.2s, border-color 0.2s',
}} }}
> >
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}> <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
<div> <div>
<h2 style={{ fontSize: '0.9375rem', fontWeight: 700, color: '#0A0A0A', margin: '0 0 4px', letterSpacing: '-0.02em' }}> <h2 style={{ fontSize: '0.9375rem', fontWeight: 700, color: 'var(--card-text)', margin: '0 0 4px', letterSpacing: '-0.02em' }}>
Design Language Design Language
</h2> </h2>
<p style={{ fontSize: '0.8125rem', color: '#71717A', margin: 0, lineHeight: 1.6 }}> <p style={{ fontSize: '0.8125rem', color: 'var(--card-muted)', margin: 0, lineHeight: 1.6 }}>
Upload a JSON schema describing your workspace&rsquo;s design tokens and component rules. Upload a JSON schema describing your workspace&rsquo;s design tokens and component rules.
</p> </p>
</div> </div>
@@ -87,8 +88,8 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
borderRadius: 8, borderRadius: 8,
fontSize: '0.8125rem', fontSize: '0.8125rem',
fontWeight: 600, fontWeight: 600,
background: status === 'uploading' ? '#E4E4E7' : '#0A0A0A', background: status === 'uploading' ? 'var(--card-subtle)' : 'var(--card-icon-bg)',
color: status === 'uploading' ? '#71717A' : '#FFFFFF', color: status === 'uploading' ? 'var(--card-muted)' : 'var(--card-icon-fg)',
border: 'none', border: 'none',
cursor: status === 'uploading' ? 'default' : 'pointer', cursor: status === 'uploading' ? 'default' : 'pointer',
fontFamily: 'inherit', fontFamily: 'inherit',
@@ -106,29 +107,29 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
style={{ style={{
marginTop: 16, marginTop: 16,
padding: '10px 14px', padding: '10px 14px',
background: '#F4F4F5', background: 'var(--card-subtle)',
borderRadius: 8, borderRadius: 8,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
gap: 10, gap: 10,
}} }}
> >
<span style={{ fontSize: '0.8125rem', color: '#3F3F46', fontWeight: 500 }}> <span style={{ fontSize: '0.8125rem', color: 'var(--card-text)', fontWeight: 500 }}>
{current.name} {current.name}
</span> </span>
<span <span
style={{ style={{
fontSize: '0.6875rem', fontSize: '0.6875rem',
padding: '2px 7px', padding: '2px 7px',
background: '#E4E4E7', background: 'var(--card-border)',
borderRadius: 4, borderRadius: 4,
color: '#71717A', color: 'var(--card-muted)',
fontFamily: "'JetBrains Mono', ui-monospace, monospace", fontFamily: "'JetBrains Mono', ui-monospace, monospace",
}} }}
> >
v{current.version} v{current.version}
</span> </span>
<span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: '#A1A1AA' }}> <span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--card-muted)' }}>
Active Active
</span> </span>
</div> </div>
@@ -27,30 +27,30 @@ export function ProjectCard({ workspaceId, projectId, name, framework, appUrl, d
<Link href={`/workspace/${workspaceId}/project/${projectId}`} style={{ textDecoration: 'none' }}> <Link href={`/workspace/${workspaceId}/project/${projectId}`} style={{ textDecoration: 'none' }}>
<div <div
style={{ style={{
background: '#FFFFFF', background: 'var(--card-bg)',
border: '1px solid rgba(0,0,0,0.07)', border: '1px solid var(--card-border)',
borderRadius: 14, padding: '20px 22px', cursor: 'pointer', borderRadius: 14, padding: '20px 22px', cursor: 'pointer',
transition: 'box-shadow 0.15s, border-color 0.15s', transition: 'box-shadow 0.15s, border-color 0.15s',
}} }}
onMouseEnter={e => { onMouseEnter={e => {
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.08)'; (e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.12)';
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.12)'; (e.currentTarget as HTMLElement).style.borderColor = 'rgba(51,133,255,0.35)';
}} }}
onMouseLeave={e => { onMouseLeave={e => {
(e.currentTarget as HTMLElement).style.boxShadow = 'none'; (e.currentTarget as HTMLElement).style.boxShadow = 'none';
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.07)'; (e.currentTarget as HTMLElement).style.borderColor = 'var(--card-border)';
}} }}
> >
<div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}> <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 14 }}>
<div style={{ <div style={{
width: 38, height: 38, borderRadius: 9, width: 38, height: 38, borderRadius: 9,
background: '#0A0A0A', background: 'var(--card-icon-bg)',
display: 'flex', alignItems: 'center', justifyContent: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center',
fontSize: '0.875rem', color: '#FFFFFF', fontWeight: 700, flexShrink: 0, fontSize: '0.875rem', color: 'var(--card-icon-fg)', fontWeight: 700, flexShrink: 0,
}}> }}>
{icon} {icon}
</div> </div>
<span style={{ fontSize: '0.9375rem', fontWeight: 600, color: '#0A0A0A', letterSpacing: '-0.01em' }}> <span style={{ fontSize: '0.9375rem', fontWeight: 600, color: 'var(--card-text)', letterSpacing: '-0.01em' }}>
{name} {name}
</span> </span>
</div> </div>
@@ -59,14 +59,14 @@ export function ProjectCard({ workspaceId, projectId, name, framework, appUrl, d
<p style={{ <p style={{
margin: '0 0 6px', margin: '0 0 6px',
fontSize: '0.75rem', fontFamily: 'monospace', fontSize: '0.75rem', fontFamily: 'monospace',
color: '#71717A', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: 'var(--card-muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
}}> }}>
{appUrl} {appUrl}
</p> </p>
)} )}
{description && ( {description && (
<p style={{ margin: '0 0 12px', fontSize: '0.8125rem', color: '#71717A', lineHeight: 1.5 }}> <p style={{ margin: '0 0 12px', fontSize: '0.8125rem', color: 'var(--card-muted)', lineHeight: 1.5 }}>
{description} {description}
</p> </p>
)} )}
@@ -14,18 +14,19 @@ interface ProjectSettingsFormProps {
} }
const SECTION: React.CSSProperties = { const SECTION: React.CSSProperties = {
background: '#FFFFFF', background: 'var(--card-bg)',
border: '1px solid rgba(0,0,0,0.07)', border: '1px solid var(--card-border)',
borderRadius: 14, borderRadius: 14,
padding: '24px 28px', padding: '24px 28px',
marginBottom: 20, marginBottom: 20,
transition: 'background 0.2s, border-color 0.2s',
}; };
const LABEL: React.CSSProperties = { const LABEL: React.CSSProperties = {
display: 'block', display: 'block',
fontSize: '0.8125rem', fontSize: '0.8125rem',
fontWeight: 600, fontWeight: 600,
color: '#0A0A0A', color: 'var(--card-text)',
marginBottom: 6, marginBottom: 6,
}; };
@@ -33,17 +34,17 @@ const INPUT: React.CSSProperties = {
width: '100%', width: '100%',
fontSize: '0.875rem', fontSize: '0.875rem',
padding: '9px 12px', padding: '9px 12px',
border: '1px solid rgba(0,0,0,0.12)', border: '1px solid var(--input-border)',
borderRadius: 9, borderRadius: 9,
fontFamily: "'Inter', -apple-system, sans-serif", fontFamily: "'Inter', -apple-system, sans-serif",
color: '#0A0A0A', color: 'var(--input-text)',
background: '#FAFAFA', background: 'var(--input-bg)',
boxSizing: 'border-box', boxSizing: 'border-box',
}; };
const BTN_PRIMARY: React.CSSProperties = { const BTN_PRIMARY: React.CSSProperties = {
display: 'inline-flex', alignItems: 'center', gap: 6, display: 'inline-flex', alignItems: 'center', gap: 6,
background: '#0A0A0A', color: '#FFFFFF', background: 'var(--btn-bg)', color: 'var(--btn-fg)',
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
padding: '9px 20px', borderRadius: 9, padding: '9px 20px', borderRadius: 9,
border: 'none', cursor: 'pointer', letterSpacing: '-0.01em', border: 'none', cursor: 'pointer', letterSpacing: '-0.01em',
@@ -126,7 +127,7 @@ export function ProjectSettingsForm({
<> <>
{/* General */} {/* General */}
<div style={SECTION}> <div style={SECTION}>
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#0A0A0A', margin: '0 0 20px' }}>General</h2> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 20px' }}>General</h2>
<label style={LABEL} htmlFor="proj-name">Project name</label> <label style={LABEL} htmlFor="proj-name">Project name</label>
<input <input
@@ -195,7 +196,7 @@ export function ProjectSettingsForm({
)} )}
{!isOwnerOrDev && ( {!isOwnerOrDev && (
<span style={{ fontSize: '0.75rem', color: '#71717A' }}>Only Designers, Developers, and Owners can edit project settings.</span> <span style={{ fontSize: '0.75rem', color: 'var(--card-muted)' }}>Only Designers, Developers, and Owners can edit project settings.</span>
)} )}
</div> </div>
@@ -205,7 +206,7 @@ export function ProjectSettingsForm({
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}>
Danger zone Danger zone
</h2> </h2>
<p style={{ fontSize: '0.8125rem', color: '#71717A', margin: '0 0 16px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.8125rem', color: 'var(--card-muted)', margin: '0 0 16px', lineHeight: 1.6 }}>
Deleting this project is permanent. All artboards, diffs, and origins will be removed. To confirm, Deleting this project is permanent. All artboards, diffs, and origins will be removed. To confirm,
type the project name below. type the project name below.
</p> </p>
@@ -22,20 +22,20 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
<Link href={`/workspace/${id}`} style={{ textDecoration: 'none' }}> <Link href={`/workspace/${id}`} style={{ textDecoration: 'none' }}>
<div <div
style={{ style={{
background: '#FFFFFF', background: 'var(--card-bg)',
border: '1px solid rgba(0,0,0,0.07)', border: '1px solid var(--card-border)',
borderRadius: 14, borderRadius: 14,
padding: '20px 22px', padding: '20px 22px',
cursor: 'pointer', cursor: 'pointer',
transition: 'box-shadow 0.15s, border-color 0.15s', transition: 'box-shadow 0.15s, border-color 0.15s',
}} }}
onMouseEnter={e => { onMouseEnter={e => {
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.08)'; (e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.12)';
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.12)'; (e.currentTarget as HTMLElement).style.borderColor = 'rgba(51,133,255,0.35)';
}} }}
onMouseLeave={e => { onMouseLeave={e => {
(e.currentTarget as HTMLElement).style.boxShadow = 'none'; (e.currentTarget as HTMLElement).style.boxShadow = 'none';
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.07)'; (e.currentTarget as HTMLElement).style.borderColor = 'var(--card-border)';
}} }}
> >
{/* Workspace icon */} {/* Workspace icon */}
@@ -54,7 +54,7 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
</div> </div>
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 8 }}> <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 8 }}>
<span style={{ fontSize: '0.9375rem', fontWeight: 600, color: '#0A0A0A', letterSpacing: '-0.01em', lineHeight: 1.3 }}> <span style={{ fontSize: '0.9375rem', fontWeight: 600, color: 'var(--card-text)', letterSpacing: '-0.01em', lineHeight: 1.3 }}>
{name} {name}
</span> </span>
<span style={{ <span style={{
@@ -66,7 +66,7 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
</span> </span>
</div> </div>
<p style={{ margin: '6px 0 0', fontSize: '0.8125rem', color: '#A1A1AA' }}> <p style={{ margin: '6px 0 0', fontSize: '0.8125rem', color: 'var(--card-muted)' }}>
Created {new Date(createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })} Created {new Date(createdAt).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}
</p> </p>
@@ -10,18 +10,19 @@ interface WorkspaceSettingsFormProps {
} }
const SECTION: React.CSSProperties = { const SECTION: React.CSSProperties = {
background: '#FFFFFF', background: 'var(--card-bg)',
border: '1px solid rgba(0,0,0,0.07)', border: '1px solid var(--card-border)',
borderRadius: 14, borderRadius: 14,
padding: '24px 28px', padding: '24px 28px',
marginBottom: 20, marginBottom: 20,
transition: 'background 0.2s, border-color 0.2s',
}; };
const LABEL: React.CSSProperties = { const LABEL: React.CSSProperties = {
display: 'block', display: 'block',
fontSize: '0.8125rem', fontSize: '0.8125rem',
fontWeight: 600, fontWeight: 600,
color: '#0A0A0A', color: 'var(--card-text)',
marginBottom: 6, marginBottom: 6,
}; };
@@ -29,17 +30,17 @@ const INPUT: React.CSSProperties = {
width: '100%', width: '100%',
fontSize: '0.875rem', fontSize: '0.875rem',
padding: '9px 12px', padding: '9px 12px',
border: '1px solid rgba(0,0,0,0.12)', border: '1px solid var(--input-border)',
borderRadius: 9, borderRadius: 9,
fontFamily: "'Inter', -apple-system, sans-serif", fontFamily: "'Inter', -apple-system, sans-serif",
color: '#0A0A0A', color: 'var(--input-text)',
background: '#FAFAFA', background: 'var(--input-bg)',
boxSizing: 'border-box', boxSizing: 'border-box',
}; };
const BTN_PRIMARY: React.CSSProperties = { const BTN_PRIMARY: React.CSSProperties = {
display: 'inline-flex', alignItems: 'center', gap: 6, display: 'inline-flex', alignItems: 'center', gap: 6,
background: '#0A0A0A', color: '#FFFFFF', background: 'var(--btn-bg)', color: 'var(--btn-fg)',
fontSize: '0.875rem', fontWeight: 600, fontSize: '0.875rem', fontWeight: 600,
padding: '9px 20px', borderRadius: 9, padding: '9px 20px', borderRadius: 9,
border: 'none', cursor: 'pointer', letterSpacing: '-0.01em', border: 'none', cursor: 'pointer', letterSpacing: '-0.01em',
@@ -99,8 +100,8 @@ function TeamInviteForm({ workspaceId }: { workspaceId: string }) {
style={{ style={{
fontSize: '0.75rem', fontWeight: 600, padding: '5px 13px', borderRadius: 8, fontSize: '0.75rem', fontWeight: 600, padding: '5px 13px', borderRadius: 8,
border: `1px solid ${role === r ? '#0066FF' : 'rgba(0,0,0,0.12)'}`, border: `1px solid ${role === r ? '#0066FF' : 'rgba(0,0,0,0.12)'}`,
background: role === r ? 'rgba(0,102,255,0.08)' : '#FFFFFF', background: role === r ? 'rgba(0,102,255,0.08)' : 'var(--btn-idle-bg)',
color: role === r ? '#0066FF' : '#52525B', color: role === r ? '#0066FF' : 'var(--btn-idle-fg)',
cursor: 'pointer', cursor: 'pointer',
}} }}
> >
@@ -228,7 +229,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
<> <>
{/* General */} {/* General */}
<div style={SECTION}> <div style={SECTION}>
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#0A0A0A', margin: '0 0 20px' }}> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 20px' }}>
General General
</h2> </h2>
<label style={LABEL} htmlFor="ws-name">Workspace name</label> <label style={LABEL} htmlFor="ws-name">Workspace name</label>
@@ -257,16 +258,16 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
<span style={{ fontSize: '0.75rem', color: '#EF4444' }}>Rename failed try again</span> <span style={{ fontSize: '0.75rem', color: '#EF4444' }}>Rename failed try again</span>
)} )}
{!isOwner && ( {!isOwner && (
<span style={{ fontSize: '0.75rem', color: '#71717A' }}>Only workspace owners can rename.</span> <span style={{ fontSize: '0.75rem', color: 'var(--card-muted)' }}>Only workspace owners can rename.</span>
)} )}
</div> </div>
{/* IDE Integration */} {/* IDE Integration */}
<div style={SECTION}> <div style={SECTION}>
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#0A0A0A', margin: '0 0 6px' }}> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 6px' }}>
IDE Integration IDE Integration
</h2> </h2>
<p style={{ fontSize: '0.8125rem', color: '#71717A', margin: '0 0 20px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.8125rem', color: 'var(--card-muted)', margin: '0 0 20px', lineHeight: 1.6 }}>
Issue a signed workspace token and copy the config snippet into your editor. Tokens expire after 30 days. Issue a signed workspace token and copy the config snippet into your editor. Tokens expire after 30 days.
</p> </p>
@@ -278,9 +279,9 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
onClick={() => setAgentType(t)} onClick={() => setAgentType(t)}
style={{ style={{
fontSize: '0.75rem', fontWeight: 600, padding: '6px 14px', borderRadius: 8, fontSize: '0.75rem', fontWeight: 600, padding: '6px 14px', borderRadius: 8,
border: `1px solid ${agentType === t ? '#0066FF' : 'rgba(0,0,0,0.12)'}`, border: `1px solid ${agentType === t ? '#0066FF' : 'var(--btn-idle-border)'}`,
background: agentType === t ? 'rgba(0,102,255,0.08)' : '#FFFFFF', background: agentType === t ? 'rgba(0,102,255,0.08)' : 'var(--btn-idle-bg)',
color: agentType === t ? '#0066FF' : '#52525B', color: agentType === t ? '#0066FF' : 'var(--btn-idle-fg)',
cursor: 'pointer', cursor: 'pointer',
}} }}
> >
@@ -335,7 +336,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
}}> }}>
{configText} {configText}
</pre> </pre>
<p style={{ fontSize: '0.75rem', color: '#71717A', marginTop: 8, lineHeight: 1.5 }}> <p style={{ fontSize: '0.75rem', color: 'var(--card-muted)', marginTop: 8, lineHeight: 1.5 }}>
Paste this into your{' '} Paste this into your{' '}
{agentType === 'CURSOR' ? ( {agentType === 'CURSOR' ? (
<code style={{ fontFamily: 'monospace', background: 'rgba(0,0,0,0.06)', padding: '1px 5px', borderRadius: 4 }}>.cursorrules</code> <code style={{ fontFamily: 'monospace', background: 'rgba(0,0,0,0.06)', padding: '1px 5px', borderRadius: 4 }}>.cursorrules</code>
@@ -351,10 +352,10 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
{/* Team */} {/* Team */}
{isOwner && ( {isOwner && (
<div style={SECTION}> <div style={SECTION}>
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#0A0A0A', margin: '0 0 6px' }}> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: 'var(--card-text)', margin: '0 0 6px' }}>
Team Team
</h2> </h2>
<p style={{ fontSize: '0.8125rem', color: '#71717A', margin: '0 0 20px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.8125rem', color: 'var(--card-muted)', margin: '0 0 20px', lineHeight: 1.6 }}>
Add a team member using their Clerk user ID. You can find this in the Clerk dashboard under Users. Add a team member using their Clerk user ID. You can find this in the Clerk dashboard under Users.
</p> </p>
@@ -368,7 +369,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}> <h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}>
Danger zone Danger zone
</h2> </h2>
<p style={{ fontSize: '0.8125rem', color: '#71717A', margin: '0 0 16px', lineHeight: 1.6 }}> <p style={{ fontSize: '0.8125rem', color: 'var(--card-muted)', margin: '0 0 16px', lineHeight: 1.6 }}>
Deleting this workspace is permanent and cannot be undone. All projects and artboards will be lost. Deleting this workspace is permanent and cannot be undone. All projects and artboards will be lost.
</p> </p>
<button <button
File diff suppressed because one or more lines are too long