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
0 ? 10 : 24 }}> @@ -898,7 +898,7 @@ function SurfacePicker({ border: `1px solid ${isSelected ? "#1a1a1a" : "#e8e4dc"}`, background: isSelected ? "#1a1a1a08" : "#fff", boxShadow: isSelected ? "0 0 0 1px #1a1a1a" : "0 1px 2px #1a1a1a05", - cursor: "pointer", transition: "all 0.12s", fontFamily: "Outfit", + cursor: "pointer", transition: "all 0.12s", fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", position: "relative", }} onMouseEnter={e => { if (!isSelected) (e.currentTarget.style.borderColor = "#d0ccc4"); }} @@ -937,7 +937,7 @@ function SurfacePicker({ padding: "9px 20px", borderRadius: 7, border: "none", background: selected.size === 0 || saving ? "#e0dcd4" : "#1a1a1a", color: selected.size === 0 || saving ? "#b5b0a6" : "#fff", - fontSize: "0.82rem", fontWeight: 600, fontFamily: "Outfit", + fontSize: "0.82rem", fontWeight: 600, fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", cursor: selected.size === 0 || saving ? "not-allowed" : "pointer", transition: "opacity 0.15s", }} @@ -947,7 +947,7 @@ function SurfacePicker({ {saving ? "Saving…" : `Confirm surfaces (${selected.size})`} → {selected.size === 0 && ( -
+
Select at least one surface to continue
)} @@ -1056,7 +1056,7 @@ function DesignPageInner({ projectId }: { projectId: string }) { if (loading) { return ( -✓ All locked
+✓ All locked
)}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 ( -
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 ( -
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",
}}>
@@ -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({
- +
+
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 (@@ -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 ( -
@@ -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 (
@@ -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 ( -
@@ -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 (
@@ -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", }}> -
@@ -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.
{summary || `${projectName} — review your current infrastructure below.`}
{projectName} — four phased migration with rollback plan