feat(ui): apply Justine ink & parchment design system

- Map Justine tokens to shadcn CSS variables (--vibn-* aliases)
- Switch fonts to Inter + Lora via next/font (IBM Plex Mono for code)
- Base typography: body Inter, h1–h3 Lora; marketing hero + wordmark serif
- Project shell and global chrome use semantic colors
- Replace Outfit/Newsreader references across TSX inline styles

Made-with: Cursor
This commit is contained in:
2026-04-01 21:03:40 -07:00
parent 06238f958a
commit bada63452f
33 changed files with 300 additions and 286 deletions

View File

@@ -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")}

View File

@@ -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")}

View File

@@ -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",

View File

@@ -47,7 +47,7 @@ export function FreshIdeaSetup({ workspace, onClose }: SetupProps) {
return (
<div style={{ padding: "32px 36px 36px" }}>
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 28 }}>
<div style={{ fontSize: "1.15rem", fontWeight: 600, color: "#1a1a1a", fontFamily: "Newsreader, serif" }}>
<div style={{ fontSize: "1.15rem", fontWeight: 600, color: "#1a1a1a", fontFamily: "var(--font-lora), ui-serif, serif" }}>
New project
</div>
<button

View File

@@ -114,7 +114,7 @@ export function MigrateSetup({ workspace, onClose, onBack }: SetupProps) {
width: "100%", padding: "11px 14px", marginBottom: 16,
borderRadius: 8, border: "1px solid #e0dcd4",
background: "#faf8f5", fontSize: "0.88rem",
fontFamily: "Outfit, sans-serif", color: hosting ? "#1a1a1a" : "#a09a90",
fontFamily: "var(--font-inter), ui-sans-serif, sans-serif", color: hosting ? "#1a1a1a" : "#a09a90",
outline: "none", boxSizing: "border-box", appearance: "none",
backgroundImage: `url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%23a09a90' strokeWidth='1.5' strokeLinecap='round' strokeLinejoin='round'/%3E%3C/svg%3E")`,
backgroundRepeat: "no-repeat", backgroundPosition: "right 12px center",
@@ -138,7 +138,7 @@ export function MigrateSetup({ workspace, onClose, onBack }: SetupProps) {
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",
}}
onFocus={e => (e.currentTarget.style.borderColor = "#1a1a1a")}

View File

@@ -61,7 +61,7 @@ export function TypeSelector({ onSelect, onClose }: TypeSelectorProps) {
<div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 28 }}>
<div>
<h2 style={{
fontFamily: "Newsreader, serif", fontSize: "1.4rem", fontWeight: 400,
fontFamily: "var(--font-lora), ui-serif, serif", fontSize: "1.4rem", fontWeight: 400,
color: "#1a1a1a", margin: 0, marginBottom: 4,
}}>
Start a new project
@@ -97,7 +97,7 @@ export function TypeSelector({ onSelect, onClose }: TypeSelectorProps) {
background: "#faf8f5",
cursor: "pointer",
transition: "all 0.14s",
fontFamily: "Outfit, sans-serif",
fontFamily: "var(--font-inter), ui-sans-serif, sans-serif",
position: "relative",
overflow: "hidden",
}}

View File

@@ -41,7 +41,7 @@ export function SetupHeader({
</button>
<div>
<h2 style={{
fontFamily: "Newsreader, serif", fontSize: "1.3rem", fontWeight: 400,
fontFamily: "var(--font-lora), ui-serif, serif", fontSize: "1.3rem", fontWeight: 400,
color: "#1a1a1a", margin: 0, marginBottom: 3,
}}>
{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,
}}