Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/ghost-ui/.shadcn/skills.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Ghost UI is a magazine-inspired design system built on shadcn/ui with:
- **Pill geometry**: 999px border-radius on buttons, inputs, and pills
- **HK Grotesk typography**: Self-hosted, 7 weights (300-900), magazine-scale heading hierarchy
- **System font stack**: consumers bring their own typeface, magazine-scale heading hierarchy
- **4-tier shadow hierarchy**: mini, card, elevated, modal
- **97 components** across 9 categories
- **323+ CSS custom properties** with full light/dark mode support
Expand Down
65 changes: 6 additions & 59 deletions packages/ghost-ui/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
"name": "ghost-ui-base",
"type": "registry:base",
"title": "Ghost UI",
"description": "Magazine-inspired design system — pill geometry, HK Grotesk typography, 4-tier shadow hierarchy",
"description": "ghost design language",
"author": "block",
"style": "ghost",
"iconLibrary": "lucide",
"baseColor": "neutral",
"registryDependencies": ["styles-main", "font-hk-grotesk", "utils"],
"registryDependencies": ["styles-main", "font-faces", "utils"],
"dependencies": ["tw-animate-css", "clsx", "tailwind-merge"],
"devDependencies": ["tailwindcss"],
"files": [],
Expand Down Expand Up @@ -93,10 +93,10 @@
"--color-surface-dark-text": "var(--surface-dark-text)",
"--color-surface-dark-muted": "var(--surface-dark-muted)",
"--color-surface-dark-border": "var(--surface-dark-border)",
"--font-sans": "\"HK Grotesk\", sans-serif",
"--font-sans": "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif",
"--font-mono": "\"Geist Mono\", monospace",
"--font-serif": "serif",
"--font-display": "\"HK Grotesk\", sans-serif",
"--font-display": "system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif",
"--radius-pill": "999px",
"--radius-button": "999px",
"--radius-input": "999px",
Expand Down Expand Up @@ -353,7 +353,7 @@
"type": "registry:style",
"dependencies": ["tw-animate-css"],
"devDependencies": ["tailwindcss"],
"registryDependencies": ["font-hk-grotesk"],
"registryDependencies": ["font-faces"],
"files": [
{
"type": "registry:theme",
Expand All @@ -363,7 +363,7 @@
]
},
{
"name": "font-hk-grotesk-faces",
"name": "font-faces",
"type": "registry:style",
"files": [
{
Expand All @@ -373,59 +373,6 @@
}
]
},
{
"name": "font-hk-grotesk",
"type": "registry:font",
"font": {
"family": "HK Grotesk",
"provider": "google",
"import": "HK_Grotesk",
"variable": "--font-hk-grotesk",
"weight": ["300", "400", "500", "600", "700", "800", "900"],
"subsets": ["latin"]
},
"meta": {
"selfHosted": true
},
"registryDependencies": ["font-hk-grotesk-faces"],
"files": [
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-Light.woff2",
"target": "public/fonts/HKGrotesk-Light.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-Regular.woff2",
"target": "public/fonts/HKGrotesk-Regular.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-Medium.woff2",
"target": "public/fonts/HKGrotesk-Medium.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-SemiBold.woff2",
"target": "public/fonts/HKGrotesk-SemiBold.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-Bold.woff2",
"target": "public/fonts/HKGrotesk-Bold.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-ExtraBold.woff2",
"target": "public/fonts/HKGrotesk-ExtraBold.woff2"
},
{
"type": "registry:file",
"path": "src/fonts/HKGrotesk-Black.woff2",
"target": "public/fonts/HKGrotesk-Black.woff2"
}
]
},
{
"name": "utils",
"type": "registry:lib",
Expand Down
5 changes: 2 additions & 3 deletions packages/ghost-ui/scripts/build-base-vars.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,12 @@ if (!baseItem) {
name: "ghost-ui-base",
type: "registry:base",
title: "Ghost UI",
description:
"Magazine-inspired design system — pill geometry, HK Grotesk typography, 4-tier shadow hierarchy",
description: "ghost design language",
author: "block",
style: "ghost",
iconLibrary: "lucide",
baseColor: "neutral",
registryDependencies: ["styles-main", "font-hk-grotesk", "utils"],
registryDependencies: ["styles-main", "font-faces", "utils"],
dependencies: ["tw-animate-css", "clsx", "tailwind-merge"],
devDependencies: ["tailwindcss"],
files: [],
Expand Down
2 changes: 1 addition & 1 deletion packages/ghost-ui/scripts/generate-skills.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ const markdown = `# Ghost UI — Agent Skills

Ghost UI is a magazine-inspired design system built on shadcn/ui with:
- **Pill geometry**: 999px border-radius on buttons, inputs, and pills
- **HK Grotesk typography**: Self-hosted, 7 weights (300-900), magazine-scale heading hierarchy
- **System font stack**: consumers bring their own typeface, magazine-scale heading hierarchy
- **4-tier shadow hierarchy**: mini, card, elevated, modal
- **${uiItems.length} components** across ${Object.keys(categories).length} categories
- **${tokenCount}+ CSS custom properties** with full light/dark mode support
Expand Down
82 changes: 70 additions & 12 deletions packages/ghost-ui/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { Route, Routes } from "react-router";
import { Navigate, Route, Routes, useParams } from "react-router";
import ComponentPage from "@/app/components/[name]/page";
import ComponentsIndex from "@/app/components/page";
import CLIReferencePage from "@/app/docs/cli/page";
import ConceptsPage from "@/app/docs/concepts/page";
import GettingStartedPage from "@/app/docs/getting-started/page";
import DocsIndex from "@/app/docs/page";
import DriftEngineIndex from "@/app/docs/page";
import SelfHostingPage from "@/app/docs/self-hosting/page";
import ColorsPage from "@/app/foundations/colors/page";
import FoundationsIndex from "@/app/foundations/page";
import TypographyPage from "@/app/foundations/typography/page";
import HomePage from "@/app/page";
import ToolsIndex from "@/app/tools/page";
import DesignLanguageIndex from "@/app/ui/page";
import { Dock } from "@/components/docs/dock";
import { ThemeProvider } from "@/components/theme/ThemeProvider";

function ComponentRedirect() {
const { name } = useParams<{ name: string }>();
return <Navigate to={`/ui/components/${name}`} replace />;
}

export function App() {
return (
<ThemeProvider
Expand All @@ -25,16 +32,67 @@ export function App() {
<main className="min-h-screen">
<Routes>
<Route index element={<HomePage />} />
<Route path="docs" element={<DocsIndex />} />
<Route path="docs/getting-started" element={<GettingStartedPage />} />
<Route path="docs/cli" element={<CLIReferencePage />} />
<Route path="docs/concepts" element={<ConceptsPage />} />
<Route path="docs/self-hosting" element={<SelfHostingPage />} />
<Route path="components" element={<ComponentsIndex />} />
<Route path="components/:name" element={<ComponentPage />} />
<Route path="foundations" element={<FoundationsIndex />} />
<Route path="foundations/colors" element={<ColorsPage />} />
<Route path="foundations/typography" element={<TypographyPage />} />

{/* Tools */}
<Route path="tools" element={<ToolsIndex />} />
<Route path="tools/drift" element={<DriftEngineIndex />} />
<Route
path="tools/drift/getting-started"
element={<GettingStartedPage />}
/>
<Route path="tools/drift/cli" element={<CLIReferencePage />} />
<Route path="tools/drift/concepts" element={<ConceptsPage />} />
<Route
path="tools/drift/self-hosting"
element={<SelfHostingPage />}
/>

{/* Design Language */}
<Route path="ui" element={<DesignLanguageIndex />} />
<Route path="ui/foundations" element={<FoundationsIndex />} />
<Route path="ui/foundations/colors" element={<ColorsPage />} />
<Route
path="ui/foundations/typography"
element={<TypographyPage />}
/>
<Route path="ui/components" element={<ComponentsIndex />} />
<Route path="ui/components/:name" element={<ComponentPage />} />

{/* Redirects from old URLs */}
<Route path="docs" element={<Navigate to="/tools/drift" replace />} />
<Route
path="docs/getting-started"
element={<Navigate to="/tools/drift/getting-started" replace />}
/>
<Route
path="docs/cli"
element={<Navigate to="/tools/drift/cli" replace />}
/>
<Route
path="docs/concepts"
element={<Navigate to="/tools/drift/concepts" replace />}
/>
<Route
path="docs/self-hosting"
element={<Navigate to="/tools/drift/self-hosting" replace />}
/>
<Route
path="foundations"
element={<Navigate to="/ui/foundations" replace />}
/>
<Route
path="foundations/colors"
element={<Navigate to="/ui/foundations/colors" replace />}
/>
<Route
path="foundations/typography"
element={<Navigate to="/ui/foundations/typography" replace />}
/>
<Route
path="components"
element={<Navigate to="/ui/components" replace />}
/>
<Route path="components/:name" element={<ComponentRedirect />} />
</Routes>
</main>
</ThemeProvider>
Expand Down
4 changes: 2 additions & 2 deletions packages/ghost-ui/src/app/components/[name]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ function getDemoSource(
export default function ComponentPage() {
const { name } = useParams<{ name: string }>();

if (!name) return <Navigate to="/components" replace />;
if (!name) return <Navigate to="/ui/components" replace />;

const component = getComponent(name);
if (!component) return <Navigate to="/components" replace />;
if (!component) return <Navigate to="/ui/components" replace />;

const category = getCategory(component.primaryCategory);
const siblings = getComponentsByCategory(component.primaryCategory);
Expand Down
2 changes: 1 addition & 1 deletion packages/ghost-ui/src/app/components/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ export default function ComponentsIndex() {
function ComponentPill({ slug, name }: { slug: string; name: string }) {
return (
<Link
to={`/components/${slug}`}
to={`/ui/components/${slug}`}
className="component-card group relative inline-block overflow-hidden rounded-full border border-border-card hover:border-foreground/25 bg-card px-4 py-1.5 transition-colors duration-300"
>
<span className="absolute inset-0 bg-foreground origin-left scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-out" />
Expand Down
4 changes: 2 additions & 2 deletions packages/ghost-ui/src/app/docs/cli/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,11 @@ ghost viz *.json --port 8080`}

<p>
See{" "}
<Link to="/docs/concepts" className="font-semibold">
<Link to="/tools/drift/concepts" className="font-semibold">
Core Concepts
</Link>{" "}
for the ideas behind these commands, or{" "}
<Link to="/docs/getting-started" className="font-semibold">
<Link to="/tools/drift/getting-started" className="font-semibold">
Getting Started
</Link>{" "}
for a guided walkthrough.
Expand Down
4 changes: 2 additions & 2 deletions packages/ghost-ui/src/app/docs/getting-started/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,12 @@ export default defineConfig({

<p>
Next:{" "}
<Link to="/docs/concepts" className="font-semibold">
<Link to="/tools/drift/concepts" className="font-semibold">
Core Concepts
</Link>{" "}
to understand fingerprints, drift, and evolution in depth. Or jump
to the{" "}
<Link to="/docs/cli" className="font-semibold">
<Link to="/tools/drift/cli" className="font-semibold">
CLI Reference
</Link>{" "}
for every command and flag.
Expand Down
35 changes: 7 additions & 28 deletions packages/ghost-ui/src/app/docs/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
"use client";

import {
BookOpen,
Compass,
Fingerprint,
Layers,
Rocket,
Server,
} from "lucide-react";
import { BookOpen, Fingerprint, Rocket, Server } from "lucide-react";
import type { ReactNode } from "react";
import { Link } from "react-router";
import { AnimatedPageHeader } from "@/components/docs/animated-page-header";
Expand All @@ -16,7 +9,7 @@ import { useStaggerReveal } from "@/hooks/use-scroll-reveal";

const hero = {
name: "Core Concepts",
href: "/docs/concepts",
href: "/tools/drift/concepts",
description:
"Fingerprints, drift detection, evolution tracking, and fleet observability — the ideas behind Ghost.",
hook: "Start here",
Expand All @@ -31,39 +24,25 @@ const sections: {
}[] = [
{
name: "Getting Started",
href: "/docs/getting-started",
href: "/tools/drift/getting-started",
description:
"Install Ghost, create your first config, and run your first drift scan in under five minutes.",
icon: <Rocket className="size-8" strokeWidth={1.5} />,
},
{
name: "CLI Reference",
href: "/docs/cli",
href: "/tools/drift/cli",
description:
"All nine commands — scan, profile, compare, diff, ack, adopt, diverge, fleet, and viz.",
icon: <BookOpen className="size-8" strokeWidth={1.5} />,
},
{
name: "Self-Hosting",
href: "/docs/self-hosting",
href: "/tools/drift/self-hosting",
description:
"Run Ghost UI as your own design system documentation site with your registry and tokens.",
icon: <Server className="size-8" strokeWidth={1.5} />,
},
{
name: "Ghost UI",
href: "/components",
description:
"Browse the component catalogue — 49 primitives and 48 AI-native elements ready to use.",
icon: <Layers className="size-8" strokeWidth={1.5} />,
},
{
name: "Foundations",
href: "/foundations",
description:
"Color, typography, and the design tokens that underpin every Ghost UI component.",
icon: <Compass className="size-8" strokeWidth={1.5} />,
},
];

export default function DocsIndex() {
Expand All @@ -76,8 +55,8 @@ export default function DocsIndex() {
return (
<SectionWrapper>
<AnimatedPageHeader
kicker="Documentation"
title="Ghost"
kicker="Drift Engine"
title="Drift Engine"
description="Autonomous design drift detection for decentralised design ecosystems. Ghost fingerprints design systems, tracks their evolution, and surfaces divergence before it compounds."
/>

Expand Down
Loading
Loading