Add landing page + Starlight docs site (#375)
* udpated matrix * feat(site): add landing page + Starlight docs site Astro + Starlight site in site/ — a flat/paper editorial landing page plus 18 docs pages seeded from the README. Monochrome theme, hairline rules, square corners, live GitHub star count, light default + dark toggle. Deploys to GitHub Pages via .github/workflows/deploy-site.yml. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
1f3625a3e9
commit
4509b45dd5
@@ -0,0 +1,430 @@
|
||||
---
|
||||
import '@fontsource-variable/archivo';
|
||||
import '@fontsource/ibm-plex-mono/400.css';
|
||||
import '@fontsource/ibm-plex-mono/500.css';
|
||||
import '@fontsource/ibm-plex-mono/600.css';
|
||||
import '../styles/theme.css';
|
||||
import GraphDiagram from '../components/GraphDiagram.astro';
|
||||
import { getStarsLabel } from '../lib/github';
|
||||
|
||||
const base = import.meta.env.BASE_URL.replace(/\/$/, '');
|
||||
const repo = 'https://github.com/colbymchenry/codegraph';
|
||||
const npm = 'https://www.npmjs.com/package/@colbymchenry/codegraph';
|
||||
const stars = await getStarsLabel();
|
||||
const install = 'npx @colbymchenry/codegraph';
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" href={`${base}/favicon.svg`} type="image/svg+xml" />
|
||||
<title>codegraph — Understand any codebase as a graph</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="A local-first code-intelligence tool that turns any codebase into a queryable knowledge graph for AI coding agents."
|
||||
/>
|
||||
<meta property="og:title" content="codegraph" />
|
||||
<meta property="og:description" content="Understand any codebase as a graph." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="theme-color" content="#f7f6f2" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="frame">
|
||||
<header class="nav">
|
||||
<a class="wordmark" href={`${base}/`}>codegraph</a>
|
||||
<nav class="nav-links">
|
||||
<a href={`${base}/getting-started/introduction`}>Docs</a>
|
||||
<a class="opt" href={`${base}/reference/languages`}>Languages</a>
|
||||
<a href={repo}>GitHub</a>
|
||||
<a class="star" href={`${repo}/stargazers`}>
|
||||
<span class="star-glyph" aria-hidden="true">★</span>{stars}
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="hero">
|
||||
<div class="hero-left">
|
||||
<h1>Understand any codebase as a graph</h1>
|
||||
<p class="lede">
|
||||
A local-first code-intelligence tool that turns any codebase into a
|
||||
queryable knowledge graph for AI coding agents.
|
||||
</p>
|
||||
<div class="cta">
|
||||
<a class="btn btn-primary" href={`${base}/getting-started/quickstart`}>Get started</a>
|
||||
<a class="btn btn-ghost" href={`${base}/getting-started/introduction`}>View documentation</a>
|
||||
</div>
|
||||
<div class="install" data-install={install}>
|
||||
<code>{install}</code>
|
||||
<button class="copy" type="button" aria-label="Copy install command">
|
||||
<svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="1.6">
|
||||
<rect x="9" y="9" width="11" height="11" />
|
||||
<path d="M5 15V5a1 1 0 0 1 1-1h9" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-right">
|
||||
<GraphDiagram />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="features">
|
||||
<article class="feature">
|
||||
<svg class="ficon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<rect x="19" y="4" width="10" height="10" />
|
||||
<rect x="4" y="34" width="10" height="10" />
|
||||
<rect x="19" y="34" width="10" height="10" />
|
||||
<rect x="34" y="34" width="10" height="10" />
|
||||
<path d="M24 14v10M9 34v-10h30v10M24 24v10" />
|
||||
</svg>
|
||||
<h2>Tree-sitter parsing</h2>
|
||||
<p>
|
||||
Fast, incremental parsing across 20+ languages — accurate symbols and
|
||||
edges drawn from real ASTs, not guesses.
|
||||
</p>
|
||||
</article>
|
||||
<article class="feature">
|
||||
<svg class="ficon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<rect x="5" y="10" width="38" height="28" />
|
||||
<path d="M13 20l6 4-6 4M26 28h9" />
|
||||
</svg>
|
||||
<h2>MCP server</h2>
|
||||
<p>
|
||||
Expose the graph to Claude Code, Cursor, Codex, opencode, and Hermes
|
||||
over MCP — agents answer in a handful of calls.
|
||||
</p>
|
||||
</article>
|
||||
<article class="feature">
|
||||
<svg class="ficon" viewBox="0 0 48 48" fill="none" stroke="currentColor" stroke-width="1.5">
|
||||
<circle cx="16" cy="24" r="10" />
|
||||
<circle cx="16" cy="24" r="3.5" fill="currentColor" stroke="none" />
|
||||
<path d="M16 8v6M16 34v6M2 24h4M26 24h6M32 24l8-6M32 24l8 6" />
|
||||
<circle cx="41" cy="17" r="2.5" />
|
||||
<circle cx="41" cy="31" r="2.5" />
|
||||
</svg>
|
||||
<h2>Impact analysis</h2>
|
||||
<p>
|
||||
Trace callers, callees, and the full impact radius of any symbol
|
||||
before you change a line.
|
||||
</p>
|
||||
</article>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="foot">
|
||||
<span class="foot-mark">codegraph</span>
|
||||
<nav class="foot-links">
|
||||
<a href={`${base}/getting-started/introduction`}>Docs</a>
|
||||
<a href={repo}>GitHub</a>
|
||||
<a href={npm}>npm</a>
|
||||
<a href={`${repo}/blob/main/LICENSE`}>MIT</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const wrap = document.querySelector('.install');
|
||||
const btn = wrap?.querySelector('.copy');
|
||||
if (wrap && btn) {
|
||||
const original = btn.innerHTML;
|
||||
btn.addEventListener('click', async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(wrap.getAttribute('data-install') || '');
|
||||
btn.innerHTML = '<span class="copied">Copied</span>';
|
||||
setTimeout(() => (btn.innerHTML = original), 1400);
|
||||
} catch {
|
||||
/* clipboard blocked — no-op */
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
:global(html) {
|
||||
background: var(--cg-paper);
|
||||
}
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
font-family: var(--sl-font);
|
||||
color: var(--cg-ink);
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.frame {
|
||||
max-width: 1440px;
|
||||
margin: 0 auto;
|
||||
border: 1px solid var(--cg-rule);
|
||||
}
|
||||
|
||||
/* ---- nav ---- */
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1.1rem 2rem;
|
||||
border-bottom: 1px solid var(--cg-rule);
|
||||
}
|
||||
.wordmark {
|
||||
font-weight: 800;
|
||||
font-size: 1.4rem;
|
||||
letter-spacing: -0.035em;
|
||||
color: var(--cg-ink);
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav-links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2rem;
|
||||
}
|
||||
.nav-links a {
|
||||
color: var(--cg-ink);
|
||||
text-decoration: none;
|
||||
font-size: 0.98rem;
|
||||
}
|
||||
.nav-links a:not(.star):hover {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 4px;
|
||||
}
|
||||
.star {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
border: 1px solid var(--cg-rule);
|
||||
padding: 0.4rem 0.85rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
.star:hover {
|
||||
background: var(--cg-paper-press);
|
||||
}
|
||||
.star-glyph {
|
||||
font-size: 0.85em;
|
||||
}
|
||||
|
||||
/* ---- hero ---- */
|
||||
.hero {
|
||||
display: grid;
|
||||
grid-template-columns: 1.05fr 0.95fr;
|
||||
border-bottom: 1px solid var(--cg-rule);
|
||||
}
|
||||
.hero-left {
|
||||
padding: 4.5rem 3rem 4rem;
|
||||
min-width: 0; /* allow the grid cell to shrink below content width */
|
||||
}
|
||||
.hero-right {
|
||||
border-inline-start: 1px solid var(--cg-rule);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 2.5rem;
|
||||
min-width: 0; /* let the SVG scale down instead of widening the page */
|
||||
}
|
||||
h1 {
|
||||
font-size: clamp(2.4rem, 6vw, 4.6rem);
|
||||
line-height: 0.98;
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.04em;
|
||||
margin: 0 0 1.6rem;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
.lede {
|
||||
font-size: 1.18rem;
|
||||
line-height: 1.5;
|
||||
color: var(--cg-ink-2);
|
||||
max-width: 34ch;
|
||||
margin: 0 0 2.2rem;
|
||||
}
|
||||
.cta {
|
||||
display: flex;
|
||||
gap: 0.9rem;
|
||||
margin-bottom: 1.6rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.8rem 1.5rem;
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
border: 1px solid var(--cg-rule);
|
||||
transition:
|
||||
background 0.12s ease,
|
||||
color 0.12s ease;
|
||||
}
|
||||
.btn-primary {
|
||||
background: var(--cg-ink);
|
||||
color: var(--cg-paper);
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background: transparent;
|
||||
color: var(--cg-ink);
|
||||
}
|
||||
.btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--cg-ink);
|
||||
}
|
||||
.btn-ghost:hover {
|
||||
background: var(--cg-paper-press);
|
||||
}
|
||||
.install {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
border: 1px solid var(--cg-rule);
|
||||
padding: 0.5rem 0.55rem 0.5rem 0.9rem;
|
||||
font-family: var(--sl-font-mono);
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.install code {
|
||||
font-family: inherit;
|
||||
background: none;
|
||||
color: var(--cg-ink);
|
||||
}
|
||||
.copy {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
padding: 0.3rem;
|
||||
color: var(--cg-ink-2);
|
||||
}
|
||||
.copy:hover {
|
||||
color: var(--cg-ink);
|
||||
}
|
||||
.copy :global(.copied) {
|
||||
font-family: var(--sl-font);
|
||||
font-size: 0.8rem;
|
||||
padding: 0 0.2rem;
|
||||
}
|
||||
|
||||
/* ---- features ---- */
|
||||
.features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.feature {
|
||||
padding: 2.4rem 2rem 2.8rem;
|
||||
}
|
||||
.feature + .feature {
|
||||
border-inline-start: 1px solid var(--cg-rule);
|
||||
}
|
||||
.ficon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-bottom: 1.2rem;
|
||||
color: var(--cg-ink);
|
||||
}
|
||||
.feature h2 {
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 0.6rem;
|
||||
}
|
||||
.feature p {
|
||||
font-size: 1rem;
|
||||
line-height: 1.55;
|
||||
color: var(--cg-ink-2);
|
||||
margin: 0;
|
||||
max-width: 34ch;
|
||||
}
|
||||
|
||||
/* ---- footer ---- */
|
||||
.foot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 1.4rem 2rem;
|
||||
border-top: 1px solid var(--cg-rule);
|
||||
}
|
||||
.foot-mark {
|
||||
font-weight: 800;
|
||||
letter-spacing: -0.03em;
|
||||
}
|
||||
.foot-links {
|
||||
display: flex;
|
||||
gap: 1.6rem;
|
||||
}
|
||||
.foot-links a {
|
||||
color: var(--cg-ink-2);
|
||||
text-decoration: none;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
.foot-links a:hover {
|
||||
color: var(--cg-ink);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
|
||||
/* ---- restrained entrance ---- */
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.hero-left > * {
|
||||
opacity: 0;
|
||||
transform: translateY(8px);
|
||||
animation: cg-in 0.5s ease forwards;
|
||||
}
|
||||
.hero-left > *:nth-child(1) {
|
||||
animation-delay: 0.04s;
|
||||
}
|
||||
.hero-left > *:nth-child(2) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
.hero-left > *:nth-child(3) {
|
||||
animation-delay: 0.16s;
|
||||
}
|
||||
.hero-left > *:nth-child(4) {
|
||||
animation-delay: 0.22s;
|
||||
}
|
||||
@keyframes cg-in {
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- responsive ---- */
|
||||
@media (max-width: 860px) {
|
||||
.hero {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.hero-right {
|
||||
border-inline-start: none;
|
||||
border-top: 1px solid var(--cg-rule);
|
||||
}
|
||||
.features {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.feature + .feature {
|
||||
border-inline-start: none;
|
||||
border-top: 1px solid var(--cg-rule);
|
||||
}
|
||||
.nav {
|
||||
padding: 1rem 1.25rem;
|
||||
}
|
||||
.nav-links {
|
||||
gap: 0.85rem;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.nav-links .opt {
|
||||
display: none;
|
||||
}
|
||||
.star {
|
||||
display: none; /* count still lives on the GitHub page */
|
||||
}
|
||||
.hero-left {
|
||||
padding: 2.75rem 1.25rem 2.5rem;
|
||||
}
|
||||
.foot {
|
||||
flex-direction: column;
|
||||
gap: 1rem;
|
||||
align-items: flex-start;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user