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
@@ -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&rsquo;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