diff --git a/app/(marketing)/layout.tsx b/app/(marketing)/layout.tsx index 709716f..34a9b70 100644 --- a/app/(marketing)/layout.tsx +++ b/app/(marketing)/layout.tsx @@ -38,7 +38,7 @@ export default function MarketingLayout({ alt="Vib'n" className="h-8 w-8" /> - Vib'n + Vib'n
diff --git a/app/[workspace]/activity/page.tsx b/app/[workspace]/activity/page.tsx index be852e8..818bb36 100644 --- a/app/[workspace]/activity/page.tsx +++ b/app/[workspace]/activity/page.tsx @@ -58,10 +58,10 @@ export default function ActivityPage() { return (

Activity @@ -81,7 +81,7 @@ export default function ActivityPage() { background: filter === f.id ? "#1a1a1a" : "#fff", color: filter === f.id ? "#fff" : "#6b6560", fontSize: "0.75rem", fontWeight: 600, transition: "all 0.12s", - cursor: "pointer", fontFamily: "Outfit, sans-serif", + cursor: "pointer", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }} > {f.label} diff --git a/app/[workspace]/project/[projectId]/analytics/page.tsx b/app/[workspace]/project/[projectId]/analytics/page.tsx index a907135..2fad6d8 100644 --- a/app/[workspace]/project/[projectId]/analytics/page.tsx +++ b/app/[workspace]/project/[projectId]/analytics/page.tsx @@ -43,7 +43,7 @@ type SectionId = typeof SECTIONS[number]["id"]; const NAV_GROUP: React.CSSProperties = { fontSize: "0.6rem", fontWeight: 700, color: "#b5b0a6", letterSpacing: "0.09em", textTransform: "uppercase", - padding: "14px 12px 6px", fontFamily: "Outfit, sans-serif", + padding: "14px 12px 6px", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }; function AnalyticsInner() { @@ -60,7 +60,7 @@ function AnalyticsInner() { router.push(`/${workspace}/project/${projectId}/analytics?section=${id}`, { scroll: false }); return ( -
+
{/* Left nav */}
@@ -126,7 +126,7 @@ function AnalyticsInner() { export default function AnalyticsPage() { return ( - Loading…
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/assist/page.tsx b/app/[workspace]/project/[projectId]/assist/page.tsx index 521eed5..06eebf7 100644 --- a/app/[workspace]/project/[projectId]/assist/page.tsx +++ b/app/[workspace]/project/[projectId]/assist/page.tsx @@ -43,7 +43,7 @@ type SectionId = typeof SECTIONS[number]["id"]; const NAV_GROUP: React.CSSProperties = { fontSize: "0.6rem", fontWeight: 700, color: "#b5b0a6", letterSpacing: "0.09em", textTransform: "uppercase", - padding: "14px 12px 6px", fontFamily: "Outfit, sans-serif", + padding: "14px 12px 6px", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }; function AssistInner() { @@ -60,7 +60,7 @@ function AssistInner() { router.push(`/${workspace}/project/${projectId}/assist?section=${id}`, { scroll: false }); return ( -
+
{/* Left nav */}
@@ -126,7 +126,7 @@ function AssistInner() { export default function AssistPage() { return ( - Loading…
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/build/page.tsx b/app/[workspace]/project/[projectId]/build/page.tsx index 7055fdd..ab6f860 100644 --- a/app/[workspace]/project/[projectId]/build/page.tsx +++ b/app/[workspace]/project/[projectId]/build/page.tsx @@ -105,7 +105,7 @@ function TreeRow({ node, depth, selectedPath, onSelect, onToggle }: { const NAV_GROUP_LABEL: React.CSSProperties = { fontSize: "0.6rem", fontWeight: 700, color: "#b5b0a6", letterSpacing: "0.09em", textTransform: "uppercase", - padding: "12px 12px 5px", fontFamily: "Outfit, sans-serif", + padding: "12px 12px 5px", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }; function NavItem({ label, active, onClick, indent = false }: { label: string; active: boolean; onClick: () => void; indent?: boolean }) { @@ -115,7 +115,7 @@ function NavItem({ label, active, onClick, indent = false }: { label: string; ac background: active ? "#f0ece4" : "transparent", border: "none", cursor: "pointer", padding: `5px 12px 5px ${indent ? 22 : 12}px`, borderRadius: 5, fontSize: "0.78rem", fontWeight: active ? 600 : 440, - color: active ? "#1a1a1a" : "#5a5550", fontFamily: "Outfit, sans-serif", + color: active ? "#1a1a1a" : "#5a5550", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }} onMouseEnter={e => { if (!active) (e.currentTarget as HTMLElement).style.background = "#f6f4f0"; }} onMouseLeave={e => { if (!active) (e.currentTarget as HTMLElement).style.background = "transparent"; }} @@ -156,8 +156,8 @@ function InfraContent({ tab, projectId, workspace }: { tab: string; projectId: s return (
-
{tab}
- Open full view → +
{tab}
+ Open full view →
{d && }
@@ -179,8 +179,8 @@ function LayoutsContent({ surfaces, projectId, workspace, activeSurfaceId, onSel return (
-
Layouts
- Edit in Design → +
Layouts
+ Edit in Design →
{surfaces.map(s => ( @@ -191,18 +191,18 @@ function LayoutsContent({ surfaces, projectId, workspace, activeSurfaceId, onSel minWidth: 180, flex: "1 1 180px", maxWidth: 240, transition: "border-color 0.1s", }}> -
+
{SURFACE_LABELS[s.id] ?? s.id}
{s.lockedTheme ? ( -
Theme: {s.lockedTheme}
+
Theme: {s.lockedTheme}
) : ( -
Not configured
+
Not configured
)}
))}
-
+
Click a surface to select it, then open the Design editor to configure themes, fonts, and components.
@@ -507,8 +507,8 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName if (!appName) { return (
-
Select an app first
-
Choose an app from the left nav to run agent tasks against it.
+
Select an app first
+
Choose an app from the left nav to run agent tasks against it.
); } @@ -517,11 +517,11 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName
{/* Horizontal sessions strip */}
- Sessions + Sessions - {loadingSessions && Loading…} + {loadingSessions && Loading…} {!loadingSessions && sessions.length === 0 && ( - No sessions yet — run your first task below + No sessions yet — run your first task below )} {sessions.map(s => ( )}
@@ -553,14 +553,14 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName {/* Session header */}
- {activeSession.task} + {activeSession.task} {activeSession.started_at && ( - + {["running", "pending"].includes(activeSession.status) ? `${elapsed(activeSession.started_at)} elapsed` : elapsed(activeSession.started_at)} )} {["running", "pending"].includes(activeSession.status) && ( - )} @@ -596,7 +596,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName
{showFollowUp ? (
-
+
Add a follow-up instruction (optional) then retry:
@@ -607,34 +607,34 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName onKeyDown={e => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) handleRetry(followUp); if (e.key === "Escape") setShowFollowUp(false); }} placeholder="e.g. Also update the TypeScript types, or just leave blank to retry as-is…" rows={2} - style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 7, padding: "8px 11px", fontSize: "0.78rem", fontFamily: "Outfit, sans-serif", outline: "none", background: "#faf8f5" }} + style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 7, padding: "8px 11px", fontSize: "0.78rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", outline: "none", background: "#faf8f5" }} />
-
+
⌘↵ to retry · Esc to cancel · Same session, fresh run
) : (
-
+
{activeSession.status === "failed" ? "Session failed — retry without losing context" : "Session stopped"}
@@ -645,7 +645,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName {/* Changed files */} {activeSession.changed_files.length > 0 && (
-
Changed Files
+
Changed Files
{activeSession.changed_files.map((f, i) => (
@@ -655,7 +655,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName ))}
{activeSession.status === "approved" && ( -
+
✓ Auto-committed — these changes are live.
)} @@ -664,7 +664,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName {approveResult && (
@@ -694,16 +694,16 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName padding: "7px 16px", background: approveMsg.trim() ? "#1a1a1a" : "#e8e4dc", color: approveMsg.trim() ? "#fff" : "#a09a90", border: "none", borderRadius: 7, fontSize: "0.75rem", fontWeight: 600, cursor: approveMsg.trim() ? "pointer" : "default", - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }} > {approving ? "Committing…" : "Commit & push"} -
-
+
Enter to commit · Esc to cancel · Coolify will auto-deploy after push
@@ -711,14 +711,14 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName
Open in Theia → @@ -730,7 +730,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName )} ) : ( -
+
Select a session or run a new task
)} @@ -745,7 +745,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName
- + Agent is working — wait for it to finish, or stop it above.
@@ -758,15 +758,15 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName return (
- + ✓ Shipped — changes committed and deployment triggered automatically.
@@ -782,10 +782,10 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName }} placeholder="What should the agent build next?" rows={2} - style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 7, padding: "8px 11px", fontSize: "0.78rem", fontFamily: "Outfit, sans-serif", outline: "none", background: "#faf8f5" }} + style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 7, padding: "8px 11px", fontSize: "0.78rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", outline: "none", background: "#faf8f5" }} />
@@ -800,7 +800,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName
{showFollowUp ? (
-
+
Describe the next thing to build (continues from this session's context):
@@ -816,36 +816,36 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName rows={2} style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 7, - padding: "8px 11px", fontSize: "0.78rem", fontFamily: "Outfit, sans-serif", + padding: "8px 11px", fontSize: "0.78rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", outline: "none", background: "#faf8f5", }} />
-
+
⌘↵ to run · Esc to cancel · Starts a new session for this task
) : (
- + ✓ Done — approve the changes above, or continue building.
@@ -867,7 +867,7 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName rows={2} style={{ flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 8, - padding: "9px 12px", fontSize: "0.8rem", fontFamily: "Outfit, sans-serif", + padding: "9px 12px", fontSize: "0.8rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", background: "#faf8f5", }} /> @@ -878,13 +878,13 @@ function AgentMode({ projectId, appName, appPath }: { projectId: string; appName padding: "10px 18px", background: task.trim() ? "#1a1a1a" : "#e8e4dc", color: task.trim() ? "#fff" : "#a09a90", border: "none", borderRadius: 8, fontSize: "0.78rem", fontWeight: 600, cursor: task.trim() ? "pointer" : "default", - fontFamily: "Outfit, sans-serif", whiteSpace: "nowrap", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", whiteSpace: "nowrap", }} > {submitting ? "Starting…" : "Run"}
-
+
⌘↵ to start · The agent works autonomously until done · You approve before anything is committed
@@ -916,15 +916,15 @@ function TerminalPanel({ appName }: { appName: string }) { }} > - Terminal + Terminal {appName && {appName}} - Phase 4 + Phase 4 {/* Body */} {open && (
-
+
{appName ? `Live shell into the ${appName} container via xterm.js + Theia PTY — coming in Phase 4.` : "Select an app from the left, then open a live shell into its container."} @@ -979,8 +979,8 @@ function FileTree({ projectId, rootPath, selectedPath, onSelectFile }: { return (
- {treeLoading &&
Loading…
} - {!treeLoading && tree.length === 0 &&
Empty.
} + {treeLoading &&
Loading…
} + {!treeLoading && tree.length === 0 &&
Empty.
} {tree.map(n => )}
); @@ -1081,7 +1081,7 @@ function PrdContent({ projectId }: { projectId: string }) { }, [projectId]); if (loading) return ( -
Loading…
+
Loading…
); const phaseMap = new Map(savedPhases.map(p => [p.phase, p])); @@ -1095,11 +1095,11 @@ function PrdContent({ projectId }: { projectId: string }) { const totalPct = Math.round((doneCount / sections.length) * 100); return ( -
+
{prd ? (
-

Product Requirements

+

Product Requirements

PRD complete
@@ -1190,8 +1190,8 @@ function PreviewContent({ projectId, apps, activePreviewApp, onSelectApp }: {
🖥
-
No deployment URL yet
-
+
No deployment URL yet
+
Deploy an app via Coolify to see a live preview here. Once deployed, the URL will appear automatically.
@@ -1337,7 +1337,7 @@ function BuildHubInner() { }; return ( -
+
{/* ── Build content ── */}
@@ -1356,13 +1356,13 @@ function BuildHubInner() { onClick={() => navigate({ section: "code", app: app.name, root: app.path })} /> )) : ( -
No apps yet
+
No apps yet
)}
{activeApp && activeRoot && (
- Files + Files {activeApp}
@@ -1381,7 +1381,7 @@ function BuildHubInner() { onClick={() => { setActiveSurfaceId(s.id); navigate({ section: "layouts", surface: s.id }); }} /> )) : ( -
Not configured
+
Not configured
)}
)} @@ -1409,7 +1409,7 @@ function BuildHubInner() { return (
)} @@ -1492,7 +1492,7 @@ function BuildHubInner() { export default function BuildPage() { return ( - Loading…
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/deployment/page.tsx b/app/[workspace]/project/[projectId]/deployment/page.tsx index 2104797..5290aa4 100644 --- a/app/[workspace]/project/[projectId]/deployment/page.tsx +++ b/app/[workspace]/project/[projectId]/deployment/page.tsx @@ -64,7 +64,7 @@ export default function DeploymentPage() { if (loading) { return ( -
+
Loading…
); @@ -77,11 +77,11 @@ export default function DeploymentPage() { return ( @@ -117,7 +117,7 @@ export default function DeploymentPage() {
SSL Active + style={{ padding: "5px 12px", borderRadius: 7, border: "1px solid #e0dcd4", background: "#fff", color: "#1a1a1a", fontSize: "0.7rem", fontWeight: 600, textDecoration: "none", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif" }}> Open ↗
@@ -130,7 +130,7 @@ export default function DeploymentPage() {
{project.giteaRepo}
+ style={{ padding: "5px 12px", borderRadius: 7, border: "1px solid #e0dcd4", background: "#fff", color: "#1a1a1a", fontSize: "0.7rem", fontWeight: 600, textDecoration: "none", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif" }}> View ↗
@@ -166,7 +166,7 @@ export default function DeploymentPage() { diff --git a/app/[workspace]/project/[projectId]/design/page.tsx b/app/[workspace]/project/[projectId]/design/page.tsx index caa89c1..aae4b8c 100644 --- a/app/[workspace]/project/[projectId]/design/page.tsx +++ b/app/[workspace]/project/[projectId]/design/page.tsx @@ -361,7 +361,7 @@ const LIBRARY_STYLE_OPTIONS: Record = { function ConfigRow({ label, children }: { label: string; children: React.ReactNode }) { return (
- {label} + {label}
{children}
@@ -383,7 +383,7 @@ function OptionChip({ display: "flex", alignItems: "center", gap: 5, padding: multi ? "4px 9px" : "4px 11px", borderRadius: 5, border: "1px solid", - fontSize: "0.72rem", fontFamily: "Outfit", cursor: "pointer", + fontSize: "0.72rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", transition: "all 0.1s", borderColor: active ? "#1a1a1a" : "#e0dcd4", background: active ? "#1a1a1a" : "#fff", @@ -411,7 +411,7 @@ function ModeToggle({ value, onChange }: { value: string; onChange: (v: "dark" | key={m} onClick={() => onChange(id)} style={{ - padding: "4px 14px", border: "none", fontSize: "0.72rem", fontFamily: "Outfit", + padding: "4px 14px", border: "none", fontSize: "0.72rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", fontWeight: active ? 600 : 400, background: active ? "#1a1a1a" : "transparent", color: active ? "#fff" : "#8a8478", @@ -622,7 +622,7 @@ function SurfaceSection({ {ScaffoldComponent ? : ( -
+
Select a library below to preview
) @@ -647,7 +647,7 @@ function SurfaceSection({ style={{ flex: 1, padding: "7px 14px", borderRadius: 7, border: "1px solid #e0dcd4", background: "#fff", color: "#1a1a1a", fontSize: "0.76rem", fontWeight: 600, - fontFamily: "Outfit", cursor: "pointer", transition: "opacity 0.15s", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", transition: "opacity 0.15s", }} onMouseEnter={e => (e.currentTarget.style.opacity = "0.7")} onMouseLeave={e => (e.currentTarget.style.opacity = "1")} @@ -660,7 +660,7 @@ function SurfaceSection({ flex: 1, padding: "7px 14px", borderRadius: 7, border: `1px solid ${previewId && !saving ? "#1a1a1a" : "#e0dcd4"}`, background: previewId && !saving ? "#1a1a1a" : "#e0dcd4", color: previewId && !saving ? "#fff" : "#b5b0a6", - fontSize: "0.76rem", fontWeight: 600, fontFamily: "Outfit", + fontSize: "0.76rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: !previewId || saving ? "not-allowed" : "pointer", transition: "opacity 0.15s", }} @@ -670,7 +670,7 @@ function SurfaceSection({ )} {activeTheme && ( (e.currentTarget.style.color = "#1a1a1a")} onMouseLeave={e => (e.currentTarget.style.color = "#b5b0a6")} >Docs ↗ @@ -679,7 +679,7 @@ function SurfaceSection({ {/* 2. Library */}
- Library + Library
{surface.themes.map(theme => { const isActive = theme.id === previewId; @@ -693,7 +693,7 @@ function SurfaceSection({ style={{ display: "flex", alignItems: "center", gap: 4, padding: "4px 11px", borderRadius: 5, border: "1px solid", - fontSize: "0.72rem", fontFamily: "Outfit", cursor: dimmed ? "not-allowed" : "pointer", + fontSize: "0.72rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: dimmed ? "not-allowed" : "pointer", transition: "all 0.1s", opacity: dimmed ? 0.35 : 1, borderColor: isActive ? "#1a1a1a" : "#e0dcd4", background: isActive ? "#1a1a1a" : "#fff", @@ -720,7 +720,7 @@ function SurfaceSection({ {/* 4. Colour */} {availableColorThemes.length > 0 && (
- Colour + Colour
{availableColorThemes.map(ct => (
)} @@ -801,7 +801,7 @@ function SurfaceSection({ {/* Colour swatches when locked (read-only) */} {isLocked && availableColorThemes.length > 0 && (
- Colour + Colour
{availableColorThemes.map(ct => ( {selected.size === 0 && ( -

+

Select at least one surface to continue

)} @@ -1056,7 +1056,7 @@ function DesignPageInner({ projectId }: { projectId: string }) { if (loading) { return ( -
+
@@ -1072,7 +1072,7 @@ function DesignPageInner({ projectId }: { projectId: string }) { const lockedCount = Object.keys(surfaceThemes).length; return ( -
+
{/* Left nav */}
@@ -1095,7 +1095,7 @@ function DesignPageInner({ projectId }: { projectId: string }) { color: isActive ? "#1a1a1a" : "#6b6560", fontSize: "0.8rem", fontWeight: isActive ? 600 : 450, cursor: "pointer", transition: "all 0.12s", position: "relative", - fontFamily: "Outfit", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }} onMouseEnter={e => { if (!isActive) (e.currentTarget.style.background = "#f6f4f0"); }} onMouseLeave={e => { if (!isActive) (e.currentTarget.style.background = "transparent"); }} @@ -1113,11 +1113,11 @@ function DesignPageInner({ projectId }: { projectId: string }) {
{lockedCount === activeSurfaces.length && lockedCount > 0 && ( -

✓ All locked

+

✓ All locked

)}
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/grow/page.tsx b/app/[workspace]/project/[projectId]/grow/page.tsx index a9fd3cf..4709a6b 100644 --- a/app/[workspace]/project/[projectId]/grow/page.tsx +++ b/app/[workspace]/project/[projectId]/grow/page.tsx @@ -11,10 +11,10 @@ export default function GrowPage() { return (
-

+

Grow

diff --git a/app/[workspace]/project/[projectId]/growth/page.tsx b/app/[workspace]/project/[projectId]/growth/page.tsx index 6f80c74..952c2a4 100644 --- a/app/[workspace]/project/[projectId]/growth/page.tsx +++ b/app/[workspace]/project/[projectId]/growth/page.tsx @@ -43,7 +43,7 @@ type SectionId = typeof SECTIONS[number]["id"]; const NAV_GROUP: React.CSSProperties = { fontSize: "0.6rem", fontWeight: 700, color: "#b5b0a6", letterSpacing: "0.09em", textTransform: "uppercase", - padding: "14px 12px 6px", fontFamily: "Outfit, sans-serif", + padding: "14px 12px 6px", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }; function GrowthInner() { @@ -60,7 +60,7 @@ function GrowthInner() { router.push(`/${workspace}/project/${projectId}/growth?section=${id}`, { scroll: false }); return ( -

+
{/* Left nav */}
@@ -137,7 +137,7 @@ function GrowthInner() { export default function GrowthPage() { return ( - Loading…
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/infrastructure/page.tsx b/app/[workspace]/project/[projectId]/infrastructure/page.tsx index 40dfb02..46e30b8 100644 --- a/app/[workspace]/project/[projectId]/infrastructure/page.tsx +++ b/app/[workspace]/project/[projectId]/infrastructure/page.tsx @@ -285,7 +285,7 @@ function InfrastructurePageInner() { }; return ( -
+
{/* ── Left sub-nav ── */}
Loading…
}> + Loading…
}> ); diff --git a/app/[workspace]/project/[projectId]/insights/page.tsx b/app/[workspace]/project/[projectId]/insights/page.tsx index 8aa8992..aacb7eb 100644 --- a/app/[workspace]/project/[projectId]/insights/page.tsx +++ b/app/[workspace]/project/[projectId]/insights/page.tsx @@ -11,10 +11,10 @@ export default function InsightsPage() { return (
-

+

Insights

diff --git a/app/[workspace]/project/[projectId]/overview/page.tsx b/app/[workspace]/project/[projectId]/overview/page.tsx index 9afa1e4..c667095 100644 --- a/app/[workspace]/project/[projectId]/overview/page.tsx +++ b/app/[workspace]/project/[projectId]/overview/page.tsx @@ -48,7 +48,7 @@ export default function ProjectOverviewPage() { if (loading) { return ( -

+
); @@ -56,7 +56,7 @@ export default function ProjectOverviewPage() { if (!project) { return ( -
+
Project not found.
); diff --git a/app/[workspace]/project/[projectId]/prd/page.tsx b/app/[workspace]/project/[projectId]/prd/page.tsx index b33a94b..4b26990 100644 --- a/app/[workspace]/project/[projectId]/prd/page.tsx +++ b/app/[workspace]/project/[projectId]/prd/page.tsx @@ -47,7 +47,7 @@ function PhaseDataCard({ phase }: { phase: SavedPhase }) { width: "100%", textAlign: "left", padding: "10px 14px", background: "none", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "space-between", - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }} > @@ -237,7 +237,7 @@ export default function PRDPage() { if (loading) { return ( -
+
Loading…
); @@ -249,7 +249,7 @@ export default function PRDPage() { ]; return ( -
+
{/* Tab bar — only when at least one doc exists */} {(prd || architecture) && ( @@ -266,7 +266,7 @@ export default function PRDPage() { background: isActive ? "#1a1a1a" : "transparent", color: isActive ? "#fff" : t.available ? "#6b6560" : "#c5c0b8", fontSize: "0.8rem", fontWeight: isActive ? 600 : 400, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", transition: "all 0.1s", }} > @@ -305,7 +305,7 @@ export default function PRDPage() { background: archGenerating ? "#4a4640" : "#fff", color: archGenerating ? "#a09a90" : "#1a1a1a", fontSize: "0.82rem", fontWeight: 700, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: archGenerating ? "default" : "pointer", flexShrink: 0, display: "flex", alignItems: "center", gap: 8, transition: "opacity 0.15s", @@ -332,7 +332,7 @@ export default function PRDPage() { {activeTab === "prd" && prd && (
-

+

Product Requirements

@@ -343,7 +343,7 @@ export default function PRDPage() { background: "#fff", borderRadius: 10, border: "1px solid #e8e4dc", padding: "28px 32px", lineHeight: 1.8, fontSize: "0.88rem", color: "#2a2824", - whiteSpace: "pre-wrap", fontFamily: "Outfit, sans-serif", + whiteSpace: "pre-wrap", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }}> {prd}
diff --git a/app/[workspace]/project/[projectId]/settings/page.tsx b/app/[workspace]/project/[projectId]/settings/page.tsx index 231b2ac..1876fe7 100644 --- a/app/[workspace]/project/[projectId]/settings/page.tsx +++ b/app/[workspace]/project/[projectId]/settings/page.tsx @@ -122,7 +122,7 @@ export default function ProjectSettingsPage() { if (loading) { return ( -
+
); @@ -131,10 +131,10 @@ export default function ProjectSettingsPage() { return (
-

+

Project Settings

diff --git a/app/[workspace]/projects/page.tsx b/app/[workspace]/projects/page.tsx index b2a5f2b..5aa3b8f 100644 --- a/app/[workspace]/projects/page.tsx +++ b/app/[workspace]/projects/page.tsx @@ -59,7 +59,7 @@ function StatusTag({ status }: { status?: string }) { display: "inline-flex", alignItems: "center", gap: 5, padding: "3px 9px", borderRadius: 4, fontSize: "0.68rem", fontWeight: 600, letterSpacing: "0.02em", - color, background: bg, fontFamily: "Outfit, sans-serif", + color, background: bg, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", }}> {label} @@ -135,13 +135,13 @@ export default function ProjectsPage() { return (

{/* Header */}

@@ -159,7 +159,7 @@ export default function ProjectsPage() { background: "#1a1a1a", color: "#fff", border: "1px solid #1a1a1a", fontSize: "0.78rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} > + @@ -189,7 +189,7 @@ export default function ProjectsPage() { width: "100%", display: "flex", alignItems: "center", padding: "18px 22px", borderRadius: 10, background: "#fff", border: "1px solid #e8e4dc", - cursor: "pointer", fontFamily: "Outfit, sans-serif", + cursor: "pointer", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", textDecoration: "none", boxShadow: "0 1px 2px #1a1a1a05", transition: "all 0.15s", }} @@ -212,7 +212,7 @@ export default function ProjectsPage() { flexShrink: 0, }}> {p.productName[0]?.toUpperCase() ?? "P"} @@ -259,7 +259,7 @@ export default function ProjectsPage() { color: "#c0bab2", cursor: "pointer", opacity: hoveredId === p.id ? 1 : 0, transition: "opacity 0.15s, color 0.15s", - fontFamily: "Outfit, sans-serif", flexShrink: 0, + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", flexShrink: 0, }} onMouseEnter={(e) => { e.currentTarget.style.color = "#d32f2f"; }} onMouseLeave={(e) => { e.currentTarget.style.color = "#c0bab2"; }} @@ -278,7 +278,7 @@ export default function ProjectsPage() { width: "100%", display: "flex", alignItems: "center", justifyContent: "center", padding: "22px", borderRadius: 10, background: "transparent", border: "1px dashed #d0ccc4", - cursor: "pointer", fontFamily: "Outfit, sans-serif", + cursor: "pointer", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#b5b0a6", fontSize: "0.84rem", fontWeight: 500, transition: "all 0.15s", animationDelay: `${projects.length * 0.05}s`, @@ -295,7 +295,7 @@ export default function ProjectsPage() { {/* Empty state */} {!loading && projects.length === 0 && (
-

+

No projects yet

@@ -307,7 +307,7 @@ export default function ProjectsPage() { padding: "10px 22px", borderRadius: 7, background: "#1a1a1a", color: "#fff", border: "none", fontSize: "0.84rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} > Create your first project diff --git a/app/globals.css b/app/globals.css index 1da3194..222ab49 100644 --- a/app/globals.css +++ b/app/globals.css @@ -11,8 +11,8 @@ @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); - --font-sans: var(--font-outfit); - --font-serif: var(--font-newsreader); + --font-sans: var(--font-inter); + --font-serif: var(--font-lora); --font-mono: var(--font-ibm-plex-mono); --color-sidebar-ring: var(--sidebar-ring); --color-sidebar-border: var(--sidebar-border); @@ -51,38 +51,50 @@ :root { --radius: 0.5rem; - /* Stackless warm beige palette */ - --background: #f6f4f0; - --foreground: #1a1a1a; - --card: #ffffff; - --card-foreground: #1a1a1a; - --popover: #ffffff; - --popover-foreground: #1a1a1a; - --primary: #1a1a1a; - --primary-foreground: #ffffff; - --secondary: #f0ece4; - --secondary-foreground: #1a1a1a; - --muted: #f0ece4; - --muted-foreground: #a09a90; - --accent: #eae6de; - --accent-foreground: #1a1a1a; - --destructive: #d32f2f; - --border: #e8e4dc; - --input: #e0dcd4; - --ring: #d0ccc4; + /* Justine UX pack — ink & parchment (aligned with master-ai/justine/00_design-tokens.css) */ + --vibn-ink: #1a1510; + --vibn-ink2: #2c2c2a; + --vibn-ink3: #444441; + --vibn-mid: #5f5e5a; + --vibn-muted: #888780; + --vibn-stone: #b4b2a9; + --vibn-parch: #d3d1c7; + --vibn-cream: #f1efe8; + --vibn-paper: #f7f4ee; + --vibn-white: #fdfcfa; + --vibn-border: #e8e2d9; + + --background: var(--vibn-paper); + --foreground: var(--vibn-ink); + --card: var(--vibn-white); + --card-foreground: var(--vibn-ink); + --popover: var(--vibn-white); + --popover-foreground: var(--vibn-ink); + --primary: var(--vibn-ink); + --primary-foreground: var(--vibn-paper); + --secondary: var(--vibn-cream); + --secondary-foreground: var(--vibn-ink); + --muted: var(--vibn-cream); + --muted-foreground: var(--vibn-muted); + --accent: var(--vibn-cream); + --accent-foreground: var(--vibn-ink); + --destructive: #b42318; + --border: var(--vibn-border); + --input: var(--vibn-border); + --ring: var(--vibn-stone); --chart-1: oklch(0.70 0.15 60); --chart-2: oklch(0.70 0.12 210); --chart-3: oklch(0.55 0.10 220); --chart-4: oklch(0.40 0.08 230); --chart-5: oklch(0.75 0.15 70); - --sidebar: #ffffff; - --sidebar-foreground: #1a1a1a; - --sidebar-primary: #1a1a1a; - --sidebar-primary-foreground: #ffffff; - --sidebar-accent: #f6f4f0; - --sidebar-accent-foreground: #1a1a1a; - --sidebar-border: #e8e4dc; - --sidebar-ring: #d0ccc4; + --sidebar: var(--vibn-white); + --sidebar-foreground: var(--vibn-ink); + --sidebar-primary: var(--vibn-ink); + --sidebar-primary-foreground: var(--vibn-paper); + --sidebar-accent: var(--vibn-paper); + --sidebar-accent-foreground: var(--vibn-ink); + --sidebar-border: var(--vibn-border); + --sidebar-ring: var(--vibn-stone); } .dark { @@ -111,8 +123,8 @@ --chart-5: oklch(0.645 0.246 16.439); --sidebar: oklch(0.205 0 0); --sidebar-foreground: oklch(0.985 0 0); - --sidebar-primary: oklch(0.488 0.243 264.376); - --sidebar-primary-foreground: oklch(0.985 0 0); + --sidebar-primary: oklch(0.85 0.02 85); + --sidebar-primary-foreground: oklch(0.18 0.02 60); --sidebar-accent: oklch(0.269 0 0); --sidebar-accent-foreground: oklch(0.985 0 0); --sidebar-border: oklch(1 0 0 / 10%); @@ -125,21 +137,24 @@ } body { @apply bg-background text-foreground; - font-family: var(--font-outfit), 'Outfit', sans-serif; + font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif; + } + h1, h2, h3 { + font-family: var(--font-lora), ui-serif, Georgia, serif; } button { - font-family: var(--font-outfit), 'Outfit', sans-serif; + font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif; cursor: pointer; } input, textarea, select { - font-family: var(--font-outfit), 'Outfit', sans-serif; + font-family: var(--font-inter), ui-sans-serif, system-ui, sans-serif; } input::placeholder { - color: #b5b0a6; + color: var(--muted-foreground); } ::selection { - background: #1a1a1a; - color: #fff; + background: var(--foreground); + color: var(--background); } ::-webkit-scrollbar { width: 4px; @@ -149,7 +164,7 @@ background: transparent; } ::-webkit-scrollbar-thumb { - background: #d0ccc4; + background: var(--vibn-stone); border-radius: 10px; } } diff --git a/app/layout.tsx b/app/layout.tsx index aec0b3e..eb88285 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,19 +1,19 @@ import type { Metadata } from "next"; -import { Outfit, Newsreader, IBM_Plex_Mono } from "next/font/google"; +import { Inter, Lora, IBM_Plex_Mono } from "next/font/google"; import "./globals.css"; import { Toaster } from "@/components/ui/sonner"; import { Providers } from "@/app/components/Providers"; -const outfit = Outfit({ - variable: "--font-outfit", +const inter = Inter({ + variable: "--font-inter", subsets: ["latin"], - weight: ["300", "400", "500", "600", "700"], + weight: ["400", "500", "600", "700"], }); -const newsreader = Newsreader({ - variable: "--font-newsreader", +const lora = Lora({ + variable: "--font-lora", subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "600", "700"], style: ["normal", "italic"], }); @@ -34,7 +34,7 @@ export const metadata: Metadata = { }, other: { "mobile-web-app-capable": "yes", - "msapplication-TileColor": "#1a1a1a", + "msapplication-TileColor": "#1a1510", }, }; @@ -47,12 +47,12 @@ export default function RootLayout({ - + {children} @@ -69,4 +69,3 @@ export default function RootLayout({ ); } - diff --git a/components/AtlasChat.tsx b/components/AtlasChat.tsx index f85b729..a639a34 100644 --- a/components/AtlasChat.tsx +++ b/components/AtlasChat.tsx @@ -140,7 +140,7 @@ function MessageRow({ display: "flex", alignItems: "center", justifyContent: "center", fontSize: "0.68rem", fontWeight: 700, color: isAtlas ? "#fff" : "#8a8478", - fontFamily: isAtlas ? "Newsreader, serif" : "Outfit, sans-serif", + fontFamily: isAtlas ? "var(--font-lora), ui-serif, serif" : "var(--font-inter), ui-sans-serif, sans-serif", }}> {isAtlas ? "A" : userInitial}

@@ -149,14 +149,14 @@ function MessageRow({
{isAtlas ? "Vibn" : "You"}
{/* Content */}
{renderContent(clean)} @@ -175,7 +175,7 @@ function MessageRow({ color: saved ? "#2e7d32" : "#fff", border: saved ? "1px solid #a5d6a7" : "none", fontSize: "0.78rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: saved || saving ? "default" : "pointer", transition: "all 0.15s", opacity: saving ? 0.7 : 1, @@ -186,7 +186,7 @@ function MessageRow({ {!saved && (
{phase.summary}
@@ -218,7 +218,7 @@ function MessageRow({ display: "inline-block", padding: "8px 16px", borderRadius: 7, background: "#1a1a1a", color: "#fff", fontSize: "0.76rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", textDecoration: "none", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", textDecoration: "none", }} > Review architecture → @@ -234,7 +234,7 @@ function MessageRow({ style={{ padding: "7px 14px", borderRadius: 6, border: "1px solid #e0dcd4", background: "none", fontSize: "0.74rem", color: "#6b6560", - fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} > Try again @@ -256,7 +256,7 @@ function MessageRow({ padding: "9px 18px", borderRadius: 8, border: "none", background: archState === "loading" ? "#8a8478" : "#1a1a1a", color: "#fff", fontSize: "0.78rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: archState === "loading" ? "default" : "pointer", transition: "background 0.15s", }} @@ -288,7 +288,7 @@ function TypingIndicator() {
A
{[0, 1, 2].map(d => ( @@ -425,7 +425,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { return (
@@ -466,7 +466,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { style={{ position: "absolute", top: 12, right: 16, background: "none", border: "none", cursor: "pointer", - fontSize: "0.68rem", color: "#d0ccc4", fontFamily: "Outfit, sans-serif", + fontSize: "0.68rem", color: "#d0ccc4", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", padding: "3px 7px", borderRadius: 4, transition: "color 0.12s", }} onMouseEnter={e => (e.currentTarget.style.color = "#8a8478")} @@ -504,7 +504,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { padding: "5px 12px", borderRadius: 20, border: "1px solid #e0dcd4", background: "#fff", color: "#6b6560", - fontSize: "0.73rem", fontFamily: "Outfit, sans-serif", + fontSize: "0.73rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", transition: "all 0.1s", whiteSpace: "nowrap", }} @@ -541,7 +541,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { disabled={isStreaming} style={{ flex: 1, border: "none", background: "none", - fontSize: "0.86rem", fontFamily: "Outfit, sans-serif", + fontSize: "0.86rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", padding: "8px 0", resize: "none", outline: "none", minHeight: 24, maxHeight: 120, @@ -553,7 +553,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { style={{ padding: "9px 16px", borderRadius: 7, border: "none", background: "#eae6de", color: "#8a8478", - fontSize: "0.78rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", + fontSize: "0.78rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", flexShrink: 0, display: "flex", alignItems: "center", gap: 6, }} @@ -569,7 +569,7 @@ export function AtlasChat({ projectId }: AtlasChatProps) { padding: "9px 16px", borderRadius: 7, border: "none", background: input.trim() ? "#1a1a1a" : "#eae6de", color: input.trim() ? "#fff" : "#b5b0a6", - fontSize: "0.78rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", + fontSize: "0.78rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: input.trim() ? "pointer" : "default", flexShrink: 0, transition: "all 0.15s", }} diff --git a/components/layout/coo-chat.tsx b/components/layout/coo-chat.tsx index 18465e4..2d9a544 100644 --- a/components/layout/coo-chat.tsx +++ b/components/layout/coo-chat.tsx @@ -162,7 +162,7 @@ export function CooChat({ projectId }: { projectId: string }) { margin: "8px 0 4px", opacity: 0.5, }}>
- + Discovery · COO
@@ -183,7 +183,7 @@ export function CooChat({ projectId }: { projectId: string }) { display: "flex", alignItems: "center", justifyContent: "center", fontSize: isAtlas ? "0.48rem" : "0.48rem", color: "#fff", flexShrink: 0, - fontFamily: isAtlas ? "Newsreader, serif" : "inherit", + fontFamily: isAtlas ? "var(--font-lora), ui-serif, serif" : "inherit", fontWeight: isAtlas ? 700 : 400, }}> {isAtlas ? "A" : "◈"} @@ -197,7 +197,7 @@ export function CooChat({ projectId }: { projectId: string }) { borderRadius: isUser ? 10 : 0, fontSize: isAtlas ? "0.75rem" : "0.79rem", color: isAtlas ? "#4a4540" : "#1a1a1a", - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", lineHeight: 1.6, whiteSpace: "pre-wrap", wordBreak: "break-word", @@ -248,7 +248,7 @@ export function CooChat({ projectId }: { projectId: string }) { flex: 1, resize: "none", border: "1px solid #e8e4dc", borderRadius: 10, padding: "8px 10px", fontSize: "0.79rem", - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", background: "#faf8f5", lineHeight: 1.5, }} @@ -267,7 +267,7 @@ export function CooChat({ projectId }: { projectId: string }) { }} >↑
-
+
↵ send · Shift+↵ newline
diff --git a/components/layout/project-shell.tsx b/components/layout/project-shell.tsx index 49d11ce..f1a754c 100644 --- a/components/layout/project-shell.tsx +++ b/components/layout/project-shell.tsx @@ -59,15 +59,15 @@ function ProjectShellInner({
{/* ── Top bar ── */}
@@ -75,7 +75,7 @@ function ProjectShellInner({
{projectName} @@ -105,13 +105,13 @@ function ProjectShellInner({ padding: "5px 12px", borderRadius: 8, fontSize: "0.8rem", fontWeight: isActive ? 600 : 440, - color: isActive ? "#1a1a1a" : "#8a8478", - background: isActive ? "#f0ece4" : "transparent", + color: isActive ? "var(--foreground)" : "var(--muted-foreground)", + background: isActive ? "var(--secondary)" : "transparent", textDecoration: "none", transition: "background 0.1s, color 0.1s", whiteSpace: "nowrap", }} - onMouseEnter={e => { if (!isActive) (e.currentTarget as HTMLElement).style.background = "#f6f4f0"; }} + onMouseEnter={e => { if (!isActive) (e.currentTarget as HTMLElement).style.background = "var(--muted)"; }} onMouseLeave={e => { if (!isActive) (e.currentTarget as HTMLElement).style.background = "transparent"; }} > {s.label} @@ -128,9 +128,9 @@ function ProjectShellInner({ title={`${session?.user?.name ?? session?.user?.email ?? "Account"} — Sign out`} style={{ width: 28, height: 28, borderRadius: "50%", - background: "#f0ece4", border: "none", cursor: "pointer", + background: "var(--secondary)", border: "none", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", - fontSize: "0.65rem", fontWeight: 700, color: "#6b6560", flexShrink: 0, + fontSize: "0.65rem", fontWeight: 700, color: "var(--muted-foreground)", flexShrink: 0, }} > {userInitial} diff --git a/components/layout/vibn-sidebar.tsx b/components/layout/vibn-sidebar.tsx index 1f20ff7..881ab9d 100644 --- a/components/layout/vibn-sidebar.tsx +++ b/components/layout/vibn-sidebar.tsx @@ -103,7 +103,7 @@ export function VIBNSidebar({ workspace, tabs, activeTab }: VIBNSidebarProps) { width: w, height: "100vh", background: "#fff", borderRight: "1px solid #e8e4dc", display: "flex", flexDirection: "column", - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", flexShrink: 0, overflow: "hidden", transition, position: "relative", }}> @@ -136,7 +136,7 @@ export function VIBNSidebar({ workspace, tabs, activeTab }: VIBNSidebarProps) {
VIBN
- + vibn @@ -334,7 +334,7 @@ export function VIBNSidebar({ workspace, tabs, activeTab }: VIBNSidebarProps) { diff --git a/components/project-creation/ChatImportSetup.tsx b/components/project-creation/ChatImportSetup.tsx index ab7c50a..1ec531a 100644 --- a/components/project-creation/ChatImportSetup.tsx +++ b/components/project-creation/ChatImportSetup.tsx @@ -69,7 +69,7 @@ export function ChatImportSetup({ workspace, onClose, onBack }: SetupProps) { width: "100%", padding: "12px 14px", marginBottom: 20, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.85rem", lineHeight: 1.55, - fontFamily: "Outfit, sans-serif", color: "#1a1a1a", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", resize: "vertical", boxSizing: "border-box", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} diff --git a/components/project-creation/CodeImportSetup.tsx b/components/project-creation/CodeImportSetup.tsx index cd12b40..1badb81 100644 --- a/components/project-creation/CodeImportSetup.tsx +++ b/components/project-creation/CodeImportSetup.tsx @@ -81,7 +81,7 @@ export function CodeImportSetup({ workspace, onClose, onBack }: SetupProps) { width: "100%", padding: "11px 14px", marginBottom: 20, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", - fontFamily: "Outfit, sans-serif", color: "#1a1a1a", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} diff --git a/components/project-creation/CreateProjectFlow.tsx b/components/project-creation/CreateProjectFlow.tsx index 1aa0135..96f76c4 100644 --- a/components/project-creation/CreateProjectFlow.tsx +++ b/components/project-creation/CreateProjectFlow.tsx @@ -81,7 +81,7 @@ export function CreateProjectFlow({ open, onOpenChange, workspace }: CreateProje boxShadow: "0 12px 48px rgba(26,26,26,0.16)", width: "100%", maxWidth: 520, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", pointerEvents: "all", animation: "vibn-slideUp 0.18s cubic-bezier(0.4,0,0.2,1)", transition: "max-width 0.2s ease", diff --git a/components/project-creation/FreshIdeaSetup.tsx b/components/project-creation/FreshIdeaSetup.tsx index 12e97a7..882b2b7 100644 --- a/components/project-creation/FreshIdeaSetup.tsx +++ b/components/project-creation/FreshIdeaSetup.tsx @@ -47,7 +47,7 @@ export function FreshIdeaSetup({ workspace, onClose }: SetupProps) { return (
-
+
New project

{label} @@ -94,7 +94,7 @@ export function TextInput({ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", - fontFamily: "Outfit, sans-serif", color: "#1a1a1a", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box", }; return ( @@ -135,7 +135,7 @@ export function PrimaryButton({ background: active ? "#1a1a1a" : "#e0dcd4", color: active ? "#fff" : "#b5b0a6", fontSize: "0.88rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: active ? "pointer" : "not-allowed", display: "flex", alignItems: "center", justifyContent: "center", gap: 8, }} diff --git a/components/project-main/ChatImportMain.tsx b/components/project-main/ChatImportMain.tsx index e8822e8..0ea7e2c 100644 --- a/components/project-main/ChatImportMain.tsx +++ b/components/project-main/ChatImportMain.tsx @@ -49,7 +49,7 @@ function EditableList({ {label}

{items.length === 0 && ( -

+

Nothing captured.

)} @@ -62,7 +62,7 @@ function EditableList({ style={{ flex: 1, padding: "7px 10px", borderRadius: 6, border: "1px solid #e0dcd4", background: "#faf8f5", - fontSize: "0.81rem", fontFamily: "Outfit, sans-serif", + fontSize: "0.81rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} @@ -83,7 +83,7 @@ function EditableList({ style={{ background: "none", border: "1px dashed #e0dcd4", cursor: "pointer", borderRadius: 6, padding: "5px 10px", fontSize: "0.72rem", color: "#a09a90", - fontFamily: "Outfit, sans-serif", width: "100%", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", width: "100%", }} onMouseEnter={e => (e.currentTarget.style.borderColor = "#b5b0a6")} onMouseLeave={e => (e.currentTarget.style.borderColor = "#e0dcd4")} @@ -147,9 +147,9 @@ export function ChatImportMain({ if (stage === "intake") { return (
-
+
-

+

Paste your chat history

@@ -172,7 +172,7 @@ export function ChatImportMain({ width: "100%", padding: "14px 16px", marginBottom: 16, borderRadius: 10, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.85rem", lineHeight: 1.6, - fontFamily: "Outfit, sans-serif", color: "#1a1a1a", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", resize: "vertical", boxSizing: "border-box", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} @@ -192,7 +192,7 @@ export function ChatImportMain({ background: chatText.trim().length > 20 ? "#1a1a1a" : "#e0dcd4", color: chatText.trim().length > 20 ? "#fff" : "#b5b0a6", fontSize: "0.9rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: chatText.trim().length > 20 ? "pointer" : "not-allowed", }} > @@ -206,7 +206,7 @@ export function ChatImportMain({ // ── Stage: extracting ───────────────────────────────────────────────────── if (stage === "extracting") { return ( -

+
+
-

+

What Atlas found

@@ -303,7 +303,7 @@ export function ChatImportMain({ style={{ padding: "11px 22px", borderRadius: 8, border: "none", background: "#fff", color: "#1a1a1a", - fontSize: "0.85rem", fontWeight: 700, fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontSize: "0.85rem", fontWeight: 700, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} onMouseEnter={e => (e.currentTarget.style.opacity = "0.88")} onMouseLeave={e => (e.currentTarget.style.opacity = "1")} @@ -315,7 +315,7 @@ export function ChatImportMain({ style={{ padding: "11px 22px", borderRadius: 8, border: "1px solid rgba(255,255,255,0.2)", background: "transparent", color: "#fff", - fontSize: "0.85rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontSize: "0.85rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} onMouseEnter={e => (e.currentTarget.style.background = "rgba(255,255,255,0.08)")} onMouseLeave={e => (e.currentTarget.style.background = "transparent")} diff --git a/components/project-main/CodeImportMain.tsx b/components/project-main/CodeImportMain.tsx index 7accf1c..ee7c307 100644 --- a/components/project-main/CodeImportMain.tsx +++ b/components/project-main/CodeImportMain.tsx @@ -135,9 +135,9 @@ export function CodeImportMain({ const isValid = repoUrl.trim().startsWith("http"); return (

-
+
-

+

Import your repository

@@ -161,7 +161,7 @@ export function CodeImportMain({ width: "100%", padding: "12px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", - fontFamily: "Outfit, sans-serif", color: "#1a1a1a", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box", }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} @@ -179,7 +179,7 @@ export function CodeImportMain({ width: "100%", padding: "13px", borderRadius: 8, border: "none", background: isValid ? "#1a1a1a" : "#e0dcd4", color: isValid ? "#fff" : "#b5b0a6", - fontSize: "0.9rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", + fontSize: "0.9rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: isValid ? "pointer" : "not-allowed", }} > @@ -194,7 +194,7 @@ export function CodeImportMain({ if (stage === "cloning") { const currentIdx = PROGRESS_STEPS.findIndex(s => s.key === progressStep); return ( -

+
+
-

+

Architecture map

@@ -289,7 +289,7 @@ export function CodeImportMain({ style={{ width: "100%", padding: "13px", borderRadius: 8, border: "none", background: "#1a1a1a", color: "#fff", - fontSize: "0.9rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontSize: "0.9rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} onMouseEnter={e => (e.currentTarget.style.opacity = "0.88")} onMouseLeave={e => (e.currentTarget.style.opacity = "1")} @@ -311,9 +311,9 @@ export function CodeImportMain({ return (

-
+
-

+

What should Atlas build?

@@ -331,7 +331,7 @@ export function CodeImportMain({ padding: "18px", borderRadius: 10, textAlign: "left", border: `2px solid ${selected ? "#1a1a1a" : "#e8e4dc"}`, background: selected ? "#1a1a1a08" : "#fff", - cursor: "pointer", fontFamily: "Outfit, sans-serif", + cursor: "pointer", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", transition: "all 0.12s", }} onMouseEnter={e => { if (!selected) e.currentTarget.style.borderColor = "#d0ccc4"; }} @@ -351,7 +351,7 @@ export function CodeImportMain({ width: "100%", padding: "13px", borderRadius: 8, border: "none", background: confirmedSurfaces.length > 0 ? "#1a1a1a" : "#e0dcd4", color: confirmedSurfaces.length > 0 ? "#fff" : "#b5b0a6", - fontSize: "0.9rem", fontWeight: 600, fontFamily: "Outfit, sans-serif", + fontSize: "0.9rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: confirmedSurfaces.length > 0 ? "pointer" : "not-allowed", }} > diff --git a/components/project-main/FreshIdeaMain.tsx b/components/project-main/FreshIdeaMain.tsx index 5195b33..5c92572 100644 --- a/components/project-main/FreshIdeaMain.tsx +++ b/components/project-main/FreshIdeaMain.tsx @@ -103,7 +103,7 @@ export function FreshIdeaMain({ projectId, projectName }: FreshIdeaMainProps) { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, flexShrink: 0, borderBottom: "1px solid #333", }}> -

+
✦ PRD saved — you can keep refining here or view the full document.
-
+
✦ Discovery complete — what's next?
-
+
All 6 phases captured. Generate your PRD or jump into Build.
@@ -145,7 +145,7 @@ export function FreshIdeaMain({ projectId, projectName }: FreshIdeaMainProps) { padding: "8px 16px", borderRadius: 7, border: "none", background: "#fff", color: "#1a1a1a", fontSize: "0.8rem", fontWeight: 700, - fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", transition: "opacity 0.12s", }} onMouseEnter={e => (e.currentTarget.style.opacity = "0.88")} @@ -160,7 +160,7 @@ export function FreshIdeaMain({ projectId, projectName }: FreshIdeaMainProps) { border: "1px solid rgba(255,255,255,0.2)", background: "transparent", color: "#fff", fontSize: "0.8rem", fontWeight: 600, - fontFamily: "Outfit, sans-serif", cursor: "pointer", + fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: "pointer", }} > Plan MVP → diff --git a/components/project-main/MigrateMain.tsx b/components/project-main/MigrateMain.tsx index 0a18373..b5e3a85 100644 --- a/components/project-main/MigrateMain.tsx +++ b/components/project-main/MigrateMain.tsx @@ -32,11 +32,11 @@ const HOSTING_OPTIONS = [ function MarkdownRenderer({ md }: { md: string }) { const lines = md.split('\n'); return ( -
+
{lines.map((line, i) => { - if (line.startsWith('## ')) return

{line.slice(3)}

; + if (line.startsWith('## ')) return

{line.slice(3)}

; if (line.startsWith('### ')) return

{line.slice(4)}

; - if (line.startsWith('# ')) return

{line.slice(2)}

; + if (line.startsWith('# ')) return

{line.slice(2)}

; if (line.match(/^- \[ \] /)) return (
@@ -157,9 +157,9 @@ export function MigrateMain({ const canProceed = repoUrl.trim().startsWith("http") || liveUrl.trim().startsWith("http"); return (
-
+
-

+

Tell us about your product

@@ -176,7 +176,7 @@ export function MigrateMain({ setRepoUrl(e.target.value)} placeholder="https://github.com/yourorg/your-repo" - style={{ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", fontFamily: "Outfit, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box" }} + style={{ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box" }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} onBlur={e => (e.currentTarget.style.borderColor = "#e0dcd4")} autoFocus /> @@ -185,7 +185,7 @@ export function MigrateMain({ setLiveUrl(e.target.value)} placeholder="https://yourproduct.com" - style={{ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", fontFamily: "Outfit, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box" }} + style={{ width: "100%", padding: "11px 14px", marginBottom: 16, borderRadius: 8, border: "1px solid #e0dcd4", background: "#faf8f5", fontSize: "0.9rem", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: "#1a1a1a", outline: "none", boxSizing: "border-box" }} onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")} onBlur={e => (e.currentTarget.style.borderColor = "#e0dcd4")} /> @@ -193,7 +193,7 @@ export function MigrateMain({ Current hosting provider @@ -201,7 +201,7 @@ export function MigrateMain({ Non-destructive. Your existing product stays live throughout. Atlas duplicates, never deletes.

@@ -220,7 +220,7 @@ export function MigrateMain({ ]; const currentIdx = steps.findIndex(s => s.key === progressStep); return ( -
+
@@ -250,10 +250,10 @@ export function MigrateMain({ const rows = (analysisResult?.rows as Array<{ category: string; item: string; status: string; detail?: string }>) ?? []; const summary = (analysisResult?.summary as string) ?? ''; return ( -
+
-

Audit complete

+

Audit complete

{summary || `${projectName} — review your current infrastructure below.`}

@@ -286,7 +286,7 @@ export function MigrateMain({
Atlas will generate a phased migration doc with Mirror, Validate, Cutover, and Decommission phases.
diff --git a/marketing/components/hero.tsx b/marketing/components/hero.tsx index 2c41746..847366f 100644 --- a/marketing/components/hero.tsx +++ b/marketing/components/hero.tsx @@ -10,7 +10,7 @@ export function Hero() {
{/* Main title */} -

+

{homepage.hero.title}