improved a lot of things
This commit is contained in:
@@ -24,9 +24,10 @@ export default function GlobalError({
|
||||
padding: 24,
|
||||
}}>
|
||||
<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%',
|
||||
boxShadow: '0 4px 24px rgba(0,0,0,0.06)', textAlign: 'center',
|
||||
transition: 'background 0.2s',
|
||||
}}>
|
||||
<div style={{
|
||||
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"/>
|
||||
</svg>
|
||||
</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
|
||||
</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.'}
|
||||
</p>
|
||||
<div style={{ display: 'flex', gap: 10, justifyContent: 'center' }}>
|
||||
@@ -51,7 +52,7 @@ export default function GlobalError({
|
||||
style={{
|
||||
padding: '9px 20px', borderRadius: 8,
|
||||
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',
|
||||
}}
|
||||
>
|
||||
@@ -62,7 +63,7 @@ export default function GlobalError({
|
||||
style={{
|
||||
padding: '9px 20px', borderRadius: 8,
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
background: '#F4F4F5', color: '#3F3F46',
|
||||
background: 'var(--card-subtle)', color: 'var(--btn-idle-fg)',
|
||||
border: 'none', textDecoration: 'none',
|
||||
display: 'inline-flex', alignItems: 'center',
|
||||
}}
|
||||
|
||||
@@ -20,13 +20,49 @@ html, body {
|
||||
enough for all shell pages to respond. */
|
||||
|
||||
:root {
|
||||
--page-bg: #FAFAFA;
|
||||
--page-text: #0A0A0A;
|
||||
--page-bg: #FAFAFA;
|
||||
--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"] {
|
||||
--page-bg: #0C0C10;
|
||||
--page-text: #FAFAFA;
|
||||
--page-bg: #0C0C10;
|
||||
--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 {
|
||||
|
||||
@@ -54,15 +54,15 @@ export default function OnboardingPage() {
|
||||
padding: '24px',
|
||||
}}>
|
||||
{/* 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>
|
||||
</div>
|
||||
|
||||
{/* Card */}
|
||||
<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%',
|
||||
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={{
|
||||
width: 52, height: 52, borderRadius: 13,
|
||||
@@ -77,15 +77,15 @@ export default function OnboardingPage() {
|
||||
</svg>
|
||||
</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}!
|
||||
</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.
|
||||
</p>
|
||||
|
||||
<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
|
||||
</label>
|
||||
<input
|
||||
@@ -97,14 +97,14 @@ export default function OnboardingPage() {
|
||||
style={{
|
||||
width: '100%', boxSizing: 'border-box',
|
||||
padding: '11px 13px', fontSize: '0.9375rem',
|
||||
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 9,
|
||||
color: '#0A0A0A', background: '#FFFFFF',
|
||||
border: '1px solid var(--input-border)', borderRadius: 9,
|
||||
color: 'var(--input-text)', background: 'var(--input-bg)',
|
||||
fontFamily: 'inherit',
|
||||
}}
|
||||
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}"
|
||||
</p>
|
||||
|
||||
@@ -117,8 +117,8 @@ export default function OnboardingPage() {
|
||||
marginTop: 24, width: '100%',
|
||||
padding: '12px', borderRadius: 9,
|
||||
fontSize: '0.9375rem', fontWeight: 600,
|
||||
background: loading ? '#D4D4D8' : '#0A0A0A',
|
||||
color: '#FFFFFF', border: 'none',
|
||||
background: loading ? 'var(--card-subtle)' : 'var(--btn-bg)',
|
||||
color: loading ? 'var(--card-muted)' : 'var(--btn-fg)', border: 'none',
|
||||
cursor: loading ? 'default' : 'pointer',
|
||||
fontFamily: 'inherit', letterSpacing: '-0.01em',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
|
||||
|
||||
@@ -57,10 +57,10 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
|
||||
{/* Title row */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 32 }}>
|
||||
<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
|
||||
</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
|
||||
? 'No projects yet — connect your first app to get started'
|
||||
: `${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 }}>
|
||||
<Link href={`/workspace/${wid}/plugins`} style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 6,
|
||||
background: 'transparent', color: '#71717A',
|
||||
background: 'transparent', color: 'var(--card-muted)',
|
||||
fontSize: '0.875rem', fontWeight: 500,
|
||||
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">
|
||||
<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 href={`/workspace/${wid}/settings`} style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 6,
|
||||
background: 'transparent', color: '#71717A',
|
||||
background: 'transparent', color: 'var(--card-muted)',
|
||||
fontSize: '0.875rem', fontWeight: 500,
|
||||
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">
|
||||
<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 href={`/workspace/${wid}/project/new`} style={{
|
||||
display: 'inline-flex', alignItems: 'center', gap: 6,
|
||||
background: '#0A0A0A', color: '#FFFFFF',
|
||||
background: 'var(--btn-bg)', color: 'var(--btn-fg)',
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
padding: '9px 18px', borderRadius: 9,
|
||||
textDecoration: 'none', letterSpacing: '-0.01em',
|
||||
@@ -110,8 +110,9 @@ export default async function WorkspacePage({ params }: { params: Promise<{ wid:
|
||||
{/* Empty state */}
|
||||
{projects.length === 0 && (
|
||||
<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',
|
||||
transition: 'background 0.2s',
|
||||
}}>
|
||||
<div style={{
|
||||
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"/>
|
||||
</svg>
|
||||
</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
|
||||
</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.
|
||||
</p>
|
||||
<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' }}>
|
||||
{/* Breadcrumb */}
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 32, fontSize: '0.8125rem', color: '#71717A' }}>
|
||||
<Link href="/workspaces" style={{ color: '#71717A', textDecoration: 'none' }}>Workspaces</Link>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 32, fontSize: '0.8125rem', color: 'var(--card-muted)' }}>
|
||||
<Link href="/workspaces" style={{ color: 'var(--card-muted)', textDecoration: 'none' }}>Workspaces</Link>
|
||||
<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 style={{ color: '#09090B' }}>Plugins</span>
|
||||
<span style={{ color: 'var(--page-text)' }}>Plugins</span>
|
||||
</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
|
||||
</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.
|
||||
</p>
|
||||
|
||||
{/* Coming soon card */}
|
||||
<div style={{
|
||||
background: '#FFFFFF', border: '1px solid rgba(0,0,0,0.07)', borderRadius: 14,
|
||||
padding: '40px 36px', textAlign: 'center',
|
||||
background: 'var(--card-bg)', border: '1px solid var(--card-border)', borderRadius: 14,
|
||||
padding: '40px 36px', textAlign: 'center', transition: 'background 0.2s',
|
||||
}}>
|
||||
<div style={{
|
||||
width: 52, height: 52, borderRadius: 14,
|
||||
@@ -71,10 +71,10 @@ export default async function WorkspacePluginsPage({ params }: { params: Promise
|
||||
</svg>
|
||||
</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
|
||||
</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.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -51,40 +51,42 @@ export default async function ProjectSettingsPage({
|
||||
return (
|
||||
<div style={{
|
||||
minHeight: '100dvh',
|
||||
background: '#F5F5F7',
|
||||
background: 'var(--page-bg)',
|
||||
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif",
|
||||
transition: 'background 0.2s',
|
||||
}}>
|
||||
{/* Header */}
|
||||
<div style={{
|
||||
background: '#FFFFFF',
|
||||
borderBottom: '1px solid rgba(0,0,0,0.07)',
|
||||
background: 'var(--card-bg)',
|
||||
borderBottom: '1px solid var(--card-border)',
|
||||
padding: '0 32px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
height: 56,
|
||||
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>
|
||||
</Link>
|
||||
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
|
||||
<Link href={`/workspace/${wid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: '#52525B', fontWeight: 500 }}>
|
||||
<span style={{ color: 'var(--card-border)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
|
||||
<Link href={`/workspace/${wid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: 'var(--card-muted)', fontWeight: 500 }}>
|
||||
{wsResult.data?.name ?? 'Workspace'}
|
||||
</Link>
|
||||
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
|
||||
<Link href={`/workspace/${wid}/project/${pid}`} style={{ textDecoration: 'none', fontSize: '0.875rem', color: '#52525B', fontWeight: 500 }}>
|
||||
<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: 'var(--card-muted)', fontWeight: 500 }}>
|
||||
{project.name}
|
||||
</Link>
|
||||
<span style={{ color: 'rgba(0,0,0,0.2)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
|
||||
<span style={{ fontSize: '0.875rem', color: '#0A0A0A', fontWeight: 600 }}>Settings</span>
|
||||
<span style={{ color: 'var(--card-border)', margin: '0 8px', fontSize: '0.875rem' }}>/</span>
|
||||
<span style={{ fontSize: '0.875rem', color: 'var(--card-text)', fontWeight: 600 }}>Settings</span>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<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
|
||||
</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.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -49,15 +49,15 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
const inputStyle = {
|
||||
width: '100%', boxSizing: 'border-box' as const,
|
||||
padding: '10px 12px', fontSize: '0.9375rem',
|
||||
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 8,
|
||||
color: '#0A0A0A', background: '#FFFFFF',
|
||||
border: '1px solid var(--input-border)', borderRadius: 8,
|
||||
color: 'var(--input-text)', background: 'var(--input-bg)',
|
||||
fontFamily: 'inherit',
|
||||
};
|
||||
|
||||
const labelStyle = {
|
||||
display: 'block' as const,
|
||||
fontSize: '0.8125rem', fontWeight: 600 as const,
|
||||
color: '#3F3F46', marginBottom: 6,
|
||||
color: 'var(--card-text)', marginBottom: 6,
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -69,11 +69,11 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
]} />
|
||||
|
||||
<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)' }}>
|
||||
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: '#0A0A0A', margin: '0 0 6px' }}>
|
||||
<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: 'var(--card-text)', margin: '0 0 6px' }}>
|
||||
New project
|
||||
</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.
|
||||
</p>
|
||||
|
||||
@@ -87,7 +87,7 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
placeholder="Dashboard App"
|
||||
autoFocus style={inputStyle}
|
||||
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>
|
||||
|
||||
@@ -99,9 +99,9 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
placeholder="http://localhost:3000 or https://staging.myapp.com"
|
||||
style={inputStyle}
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
@@ -113,7 +113,7 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
value={framework} onChange={e => setFramework(e.target.value)}
|
||||
style={{ ...inputStyle, color: framework ? '#0A0A0A' : '#A1A1AA', cursor: 'pointer' }}
|
||||
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>
|
||||
{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}
|
||||
style={{ ...inputStyle, resize: 'vertical', lineHeight: 1.5 }}
|
||||
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>
|
||||
|
||||
@@ -140,8 +140,8 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
<div style={{ display: 'flex', gap: 10, marginTop: 4 }}>
|
||||
<Link href={`/workspace/${wid}`} style={{
|
||||
flex: 1, textAlign: 'center', padding: '10px', borderRadius: 8,
|
||||
fontSize: '0.875rem', fontWeight: 600, color: '#3F3F46',
|
||||
background: '#F4F4F5', textDecoration: 'none',
|
||||
fontSize: '0.875rem', fontWeight: 600, color: 'var(--btn-idle-fg)',
|
||||
background: 'var(--card-subtle)', textDecoration: 'none',
|
||||
}}>
|
||||
Cancel
|
||||
</Link>
|
||||
@@ -151,8 +151,9 @@ export default function NewProjectPage({ params }: { params: Promise<{ wid: stri
|
||||
style={{
|
||||
flex: 2, padding: '10px', borderRadius: 8,
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
background: name.trim() && !loading ? '#0A0A0A' : '#D4D4D8',
|
||||
color: '#FFFFFF', border: 'none',
|
||||
background: name.trim() && !loading ? 'var(--btn-bg)' : 'var(--card-subtle)',
|
||||
color: name.trim() && !loading ? 'var(--btn-fg)' : 'var(--card-muted)',
|
||||
border: 'none',
|
||||
cursor: name.trim() && !loading ? 'pointer' : 'default',
|
||||
fontFamily: 'inherit', transition: 'background 0.15s',
|
||||
}}
|
||||
|
||||
@@ -39,16 +39,16 @@ export default function NewWorkspacePage() {
|
||||
<AppHeader breadcrumbs={[{ label: 'Workspaces', href: '/workspaces' }, { label: 'New workspace' }]} />
|
||||
|
||||
<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)' }}>
|
||||
<h1 style={{ fontSize: '1.25rem', fontWeight: 700, letterSpacing: '-0.02em', color: '#0A0A0A', margin: '0 0 6px' }}>
|
||||
<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: 'var(--card-text)', margin: '0 0 6px' }}>
|
||||
New workspace
|
||||
</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.
|
||||
</p>
|
||||
|
||||
<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
|
||||
</label>
|
||||
<input
|
||||
@@ -60,12 +60,12 @@ export default function NewWorkspacePage() {
|
||||
style={{
|
||||
width: '100%', boxSizing: 'border-box',
|
||||
padding: '10px 12px', fontSize: '0.9375rem',
|
||||
border: '1px solid rgba(0,0,0,0.12)', borderRadius: 8,
|
||||
color: '#0A0A0A', background: '#FFFFFF',
|
||||
border: '1px solid var(--input-border)', borderRadius: 8,
|
||||
color: 'var(--input-text)', background: 'var(--input-bg)',
|
||||
fontFamily: 'inherit',
|
||||
}}
|
||||
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 && (
|
||||
@@ -76,7 +76,7 @@ export default function NewWorkspacePage() {
|
||||
<Link href="/workspaces" style={{
|
||||
flex: 1, textAlign: 'center',
|
||||
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
|
||||
</Link>
|
||||
@@ -86,8 +86,9 @@ export default function NewWorkspacePage() {
|
||||
style={{
|
||||
flex: 2, padding: '10px', borderRadius: 8,
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
background: name.trim() && !loading ? '#0A0A0A' : '#D4D4D8',
|
||||
color: '#FFFFFF', border: 'none', cursor: name.trim() && !loading ? 'pointer' : 'default',
|
||||
background: name.trim() && !loading ? 'var(--btn-bg)' : 'var(--card-subtle)',
|
||||
color: name.trim() && !loading ? 'var(--btn-fg)' : 'var(--card-muted)',
|
||||
border: 'none', cursor: name.trim() && !loading ? 'pointer' : 'default',
|
||||
fontFamily: 'inherit', transition: 'background 0.15s',
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -117,29 +117,30 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
|
||||
padding: '0 14px', gap: 0,
|
||||
zIndex: 10,
|
||||
position: 'relative',
|
||||
transition: 'background 0.2s, border-color 0.2s',
|
||||
}}>
|
||||
{/* Logo */}
|
||||
<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)' }}>
|
||||
Origin<span style={{ color: '#3385FF' }}>main</span>
|
||||
<span style={{ fontSize: '0.75rem', fontWeight: 700, letterSpacing: '-0.01em', color: CT.itemHov }}>
|
||||
Origin<span style={{ color: CT.accent }}>main</span>
|
||||
</span>
|
||||
</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
|
||||
</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'}
|
||||
</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'}
|
||||
</span>
|
||||
|
||||
@@ -152,11 +153,11 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
|
||||
marginLeft: 8,
|
||||
display: 'flex', alignItems: 'center',
|
||||
textDecoration: 'none',
|
||||
color: 'rgba(255,255,255,0.25)',
|
||||
color: CT.dim,
|
||||
transition: 'color 0.12s',
|
||||
}}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.65)')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.25)')}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = CT.itemHov)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = CT.dim)}
|
||||
>
|
||||
<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"/>
|
||||
@@ -173,13 +174,13 @@ export function AppChrome({ workspaceId, projectId, workspaceName, projectName }
|
||||
title={`Switch to ${themeMode === 'dark' ? 'light' : 'dark'} mode`}
|
||||
style={{
|
||||
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',
|
||||
transition: 'color 0.12s',
|
||||
fontSize: 13,
|
||||
}}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.75)')}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = 'rgba(255,255,255,0.35)')}
|
||||
onMouseEnter={e => (e.currentTarget.style.color = CT.itemHov)}
|
||||
onMouseLeave={e => (e.currentTarget.style.color = CT.fgMuted)}
|
||||
>
|
||||
{themeMode === 'dark' ? (
|
||||
/* Sun icon */
|
||||
|
||||
@@ -53,19 +53,20 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: '#FFFFFF',
|
||||
border: '1px solid #E4E4E7',
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--card-border)',
|
||||
borderRadius: 12,
|
||||
padding: '24px 28px',
|
||||
marginTop: 32,
|
||||
transition: 'background 0.2s, border-color 0.2s',
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
|
||||
<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
|
||||
</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’s design tokens and component rules.
|
||||
</p>
|
||||
</div>
|
||||
@@ -87,8 +88,8 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
|
||||
borderRadius: 8,
|
||||
fontSize: '0.8125rem',
|
||||
fontWeight: 600,
|
||||
background: status === 'uploading' ? '#E4E4E7' : '#0A0A0A',
|
||||
color: status === 'uploading' ? '#71717A' : '#FFFFFF',
|
||||
background: status === 'uploading' ? 'var(--card-subtle)' : 'var(--card-icon-bg)',
|
||||
color: status === 'uploading' ? 'var(--card-muted)' : 'var(--card-icon-fg)',
|
||||
border: 'none',
|
||||
cursor: status === 'uploading' ? 'default' : 'pointer',
|
||||
fontFamily: 'inherit',
|
||||
@@ -106,29 +107,29 @@ export function DesignLanguageUpload({ workspaceId, current }: Props) {
|
||||
style={{
|
||||
marginTop: 16,
|
||||
padding: '10px 14px',
|
||||
background: '#F4F4F5',
|
||||
background: 'var(--card-subtle)',
|
||||
borderRadius: 8,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 10,
|
||||
}}
|
||||
>
|
||||
<span style={{ fontSize: '0.8125rem', color: '#3F3F46', fontWeight: 500 }}>
|
||||
<span style={{ fontSize: '0.8125rem', color: 'var(--card-text)', fontWeight: 500 }}>
|
||||
{current.name}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
fontSize: '0.6875rem',
|
||||
padding: '2px 7px',
|
||||
background: '#E4E4E7',
|
||||
background: 'var(--card-border)',
|
||||
borderRadius: 4,
|
||||
color: '#71717A',
|
||||
color: 'var(--card-muted)',
|
||||
fontFamily: "'JetBrains Mono', ui-monospace, monospace",
|
||||
}}
|
||||
>
|
||||
v{current.version}
|
||||
</span>
|
||||
<span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: '#A1A1AA' }}>
|
||||
<span style={{ marginLeft: 'auto', fontSize: '0.75rem', color: 'var(--card-muted)' }}>
|
||||
Active
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -27,30 +27,30 @@ export function ProjectCard({ workspaceId, projectId, name, framework, appUrl, d
|
||||
<Link href={`/workspace/${workspaceId}/project/${projectId}`} style={{ textDecoration: 'none' }}>
|
||||
<div
|
||||
style={{
|
||||
background: '#FFFFFF',
|
||||
border: '1px solid rgba(0,0,0,0.07)',
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--card-border)',
|
||||
borderRadius: 14, padding: '20px 22px', cursor: 'pointer',
|
||||
transition: 'box-shadow 0.15s, border-color 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.08)';
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.12)';
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.12)';
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(51,133,255,0.35)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(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={{
|
||||
width: 38, height: 38, borderRadius: 9,
|
||||
background: '#0A0A0A',
|
||||
background: 'var(--card-icon-bg)',
|
||||
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}
|
||||
</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}
|
||||
</span>
|
||||
</div>
|
||||
@@ -59,14 +59,14 @@ export function ProjectCard({ workspaceId, projectId, name, framework, appUrl, d
|
||||
<p style={{
|
||||
margin: '0 0 6px',
|
||||
fontSize: '0.75rem', fontFamily: 'monospace',
|
||||
color: '#71717A', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
||||
color: 'var(--card-muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
|
||||
}}>
|
||||
{appUrl}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{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}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -14,18 +14,19 @@ interface ProjectSettingsFormProps {
|
||||
}
|
||||
|
||||
const SECTION: React.CSSProperties = {
|
||||
background: '#FFFFFF',
|
||||
border: '1px solid rgba(0,0,0,0.07)',
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--card-border)',
|
||||
borderRadius: 14,
|
||||
padding: '24px 28px',
|
||||
marginBottom: 20,
|
||||
transition: 'background 0.2s, border-color 0.2s',
|
||||
};
|
||||
|
||||
const LABEL: React.CSSProperties = {
|
||||
display: 'block',
|
||||
fontSize: '0.8125rem',
|
||||
fontWeight: 600,
|
||||
color: '#0A0A0A',
|
||||
color: 'var(--card-text)',
|
||||
marginBottom: 6,
|
||||
};
|
||||
|
||||
@@ -33,17 +34,17 @@ const INPUT: React.CSSProperties = {
|
||||
width: '100%',
|
||||
fontSize: '0.875rem',
|
||||
padding: '9px 12px',
|
||||
border: '1px solid rgba(0,0,0,0.12)',
|
||||
border: '1px solid var(--input-border)',
|
||||
borderRadius: 9,
|
||||
fontFamily: "'Inter', -apple-system, sans-serif",
|
||||
color: '#0A0A0A',
|
||||
background: '#FAFAFA',
|
||||
color: 'var(--input-text)',
|
||||
background: 'var(--input-bg)',
|
||||
boxSizing: 'border-box',
|
||||
};
|
||||
|
||||
const BTN_PRIMARY: React.CSSProperties = {
|
||||
display: 'inline-flex', alignItems: 'center', gap: 6,
|
||||
background: '#0A0A0A', color: '#FFFFFF',
|
||||
background: 'var(--btn-bg)', color: 'var(--btn-fg)',
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
padding: '9px 20px', borderRadius: 9,
|
||||
border: 'none', cursor: 'pointer', letterSpacing: '-0.01em',
|
||||
@@ -126,7 +127,7 @@ export function ProjectSettingsForm({
|
||||
<>
|
||||
{/* General */}
|
||||
<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>
|
||||
<input
|
||||
@@ -195,7 +196,7 @@ export function ProjectSettingsForm({
|
||||
)}
|
||||
|
||||
{!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>
|
||||
|
||||
@@ -205,7 +206,7 @@ export function ProjectSettingsForm({
|
||||
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}>
|
||||
Danger zone
|
||||
</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,
|
||||
type the project name below.
|
||||
</p>
|
||||
|
||||
@@ -22,20 +22,20 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
|
||||
<Link href={`/workspace/${id}`} style={{ textDecoration: 'none' }}>
|
||||
<div
|
||||
style={{
|
||||
background: '#FFFFFF',
|
||||
border: '1px solid rgba(0,0,0,0.07)',
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--card-border)',
|
||||
borderRadius: 14,
|
||||
padding: '20px 22px',
|
||||
cursor: 'pointer',
|
||||
transition: 'box-shadow 0.15s, border-color 0.15s',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.08)';
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(0,0,0,0.12)';
|
||||
(e.currentTarget as HTMLElement).style.boxShadow = '0 4px 16px rgba(0,0,0,0.12)';
|
||||
(e.currentTarget as HTMLElement).style.borderColor = 'rgba(51,133,255,0.35)';
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
(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 */}
|
||||
@@ -54,7 +54,7 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
|
||||
</div>
|
||||
|
||||
<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}
|
||||
</span>
|
||||
<span style={{
|
||||
@@ -66,7 +66,7 @@ export function WorkspaceCard({ id, name, plan, createdAt }: WorkspaceCardProps)
|
||||
</span>
|
||||
</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' })}
|
||||
</p>
|
||||
|
||||
|
||||
@@ -10,18 +10,19 @@ interface WorkspaceSettingsFormProps {
|
||||
}
|
||||
|
||||
const SECTION: React.CSSProperties = {
|
||||
background: '#FFFFFF',
|
||||
border: '1px solid rgba(0,0,0,0.07)',
|
||||
background: 'var(--card-bg)',
|
||||
border: '1px solid var(--card-border)',
|
||||
borderRadius: 14,
|
||||
padding: '24px 28px',
|
||||
marginBottom: 20,
|
||||
transition: 'background 0.2s, border-color 0.2s',
|
||||
};
|
||||
|
||||
const LABEL: React.CSSProperties = {
|
||||
display: 'block',
|
||||
fontSize: '0.8125rem',
|
||||
fontWeight: 600,
|
||||
color: '#0A0A0A',
|
||||
color: 'var(--card-text)',
|
||||
marginBottom: 6,
|
||||
};
|
||||
|
||||
@@ -29,17 +30,17 @@ const INPUT: React.CSSProperties = {
|
||||
width: '100%',
|
||||
fontSize: '0.875rem',
|
||||
padding: '9px 12px',
|
||||
border: '1px solid rgba(0,0,0,0.12)',
|
||||
border: '1px solid var(--input-border)',
|
||||
borderRadius: 9,
|
||||
fontFamily: "'Inter', -apple-system, sans-serif",
|
||||
color: '#0A0A0A',
|
||||
background: '#FAFAFA',
|
||||
color: 'var(--input-text)',
|
||||
background: 'var(--input-bg)',
|
||||
boxSizing: 'border-box',
|
||||
};
|
||||
|
||||
const BTN_PRIMARY: React.CSSProperties = {
|
||||
display: 'inline-flex', alignItems: 'center', gap: 6,
|
||||
background: '#0A0A0A', color: '#FFFFFF',
|
||||
background: 'var(--btn-bg)', color: 'var(--btn-fg)',
|
||||
fontSize: '0.875rem', fontWeight: 600,
|
||||
padding: '9px 20px', borderRadius: 9,
|
||||
border: 'none', cursor: 'pointer', letterSpacing: '-0.01em',
|
||||
@@ -99,8 +100,8 @@ function TeamInviteForm({ workspaceId }: { workspaceId: string }) {
|
||||
style={{
|
||||
fontSize: '0.75rem', fontWeight: 600, padding: '5px 13px', borderRadius: 8,
|
||||
border: `1px solid ${role === r ? '#0066FF' : 'rgba(0,0,0,0.12)'}`,
|
||||
background: role === r ? 'rgba(0,102,255,0.08)' : '#FFFFFF',
|
||||
color: role === r ? '#0066FF' : '#52525B',
|
||||
background: role === r ? 'rgba(0,102,255,0.08)' : 'var(--btn-idle-bg)',
|
||||
color: role === r ? '#0066FF' : 'var(--btn-idle-fg)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
@@ -228,7 +229,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
|
||||
<>
|
||||
{/* General */}
|
||||
<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
|
||||
</h2>
|
||||
<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>
|
||||
)}
|
||||
{!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>
|
||||
|
||||
{/* IDE Integration */}
|
||||
<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
|
||||
</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.
|
||||
</p>
|
||||
|
||||
@@ -278,9 +279,9 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
|
||||
onClick={() => setAgentType(t)}
|
||||
style={{
|
||||
fontSize: '0.75rem', fontWeight: 600, padding: '6px 14px', borderRadius: 8,
|
||||
border: `1px solid ${agentType === t ? '#0066FF' : 'rgba(0,0,0,0.12)'}`,
|
||||
background: agentType === t ? 'rgba(0,102,255,0.08)' : '#FFFFFF',
|
||||
color: agentType === t ? '#0066FF' : '#52525B',
|
||||
border: `1px solid ${agentType === t ? '#0066FF' : 'var(--btn-idle-border)'}`,
|
||||
background: agentType === t ? 'rgba(0,102,255,0.08)' : 'var(--btn-idle-bg)',
|
||||
color: agentType === t ? '#0066FF' : 'var(--btn-idle-fg)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
>
|
||||
@@ -335,7 +336,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
|
||||
}}>
|
||||
{configText}
|
||||
</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{' '}
|
||||
{agentType === 'CURSOR' ? (
|
||||
<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 */}
|
||||
{isOwner && (
|
||||
<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
|
||||
</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.
|
||||
</p>
|
||||
|
||||
@@ -368,7 +369,7 @@ export function WorkspaceSettingsForm({ workspaceId, workspaceName, memberRole }
|
||||
<h2 style={{ fontSize: '1rem', fontWeight: 600, color: '#EF4444', margin: '0 0 8px' }}>
|
||||
Danger zone
|
||||
</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.
|
||||
</p>
|
||||
<button
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user