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
44 changes: 44 additions & 0 deletions DEVLOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,50 @@

> Append-only session log. Read at session start. Update at session end.

## 2026-06-16 — Public landing site (`landing/`, standalone Next app)

Built the marketing site from the Claude Design handoff bundle (`Forge
Landing Site` project). Implemented as a **standalone** Next 15 app in
`landing/` — its own `package.json`/lockfile, decoupled from the main app,
`output: "export"` → static `out/` deployable to any host. Stack: React 19,
Tailwind 3 wired to the Forge token vars, `next/font` (Inter + JetBrains
Mono), `next-themes` (light/dark). `landing/README.md` documents it.

`app/globals.css` mirrors the Forge token system from `src/app/globals.css`
(tokens + the motion/glow-grid keyframes) plus a thin **responsive layer**:
the section components are inline-styled verbatim from the prototype, and
responsiveness is layered via marker classes (`.lnd-cols-2/3/4`, `.lnd-pad`,
`.lnd-pad-left`, `.lnd-hero-grid`, `.lnd-hero-visual`, `.lnd-nav*`,
`.lnd-footer*`, `.lnd-release-row`, `.lnd-navlink`, `.lnd-doclink`) with
`!important` media-query overrides. The prototype's canvas/tweaks shell is
dropped; one responsive page replaces the separate desktop/mobile artboards.

Routes: `/` (hero → 4 pillars → 3-tier runtimes → product strip → planning →
self-host → changelog preview → footer), `/releases` (full changelog from
`lib/releases.ts`), `/docs` (docs index), branded `not-found`, plus
`robots.ts` + `sitemap.ts` + per-page OG/canonical for SEO.

Process: ported the ~10 section components by fanning out parallel subagents
(verbatim port + per-file responsive markers), each adversarially
fidelity-reviewed against the prototype; then a 3-dimension review
(responsive / a11y / correctness) caught real bugs I fixed: phone nav
overflow (hide GitHub pill + version badge < 860/520px), the self-host
install `<pre>` inverting onto `--foreground` and going invisible in dark
mode (pinned to a fixed dark terminal surface), the hero product-mock
cramping on phones (hidden < 760px, matching the mobile artboard), missing
`<h1>` + heading-level skips on sub-pages, dead in-page anchors rewired to
real routes, and trailing-slash consistency.

Intentional non-fix: the primary ember CTA is ~3.06:1 in light mode (WCAG AA
miss for 13px bold) — it's the brand `--ember` token mirrored verbatim from
the app's design system (lockstep per CLAUDE.md) and the exact button shipped
in-product, so the contrast fix belongs in the design system, not a
landing-site fork.

Verification: `pnpm typecheck`, `pnpm lint`, `pnpm build` (static export, all
routes) all green; exported HTML spot-checked (one h1/page, per-page og:url +
canonical, trailing-slash links, fixed terminal colors, sitemap).

## 2026-06-15 — Goal creation starts live planning

Closed AXI-80's silent-goal gap. Goal creation from the Goals page now chains
Expand Down
12 changes: 12 additions & 0 deletions landing/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# deps
/node_modules

# next
/.next/
/out/
next-env.d.ts

# misc
.DS_Store
*.tsbuildinfo
.vercel
97 changes: 97 additions & 0 deletions landing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Forge — Landing Site

The public marketing site for [Forge](https://github.com/Codename-11/forge). A
**standalone** Next.js app, fully decoupled from the main application: it has
its own `package.json`, its own dependencies, and emits a **static site** you
can host anywhere.

It was implemented from the `Forge Landing Site` design (Claude Design handoff
bundle) and recreates that design pixel-for-pixel using the same Forge token
system (`globals.css` mirrors `src/app/globals.css` from the main repo).

## Stack

Next.js 15 (App Router, `output: "export"`) · React 19 · TypeScript ·
Tailwind 3 (wired to the Forge token CSS vars) · `next/font` (Inter +
JetBrains Mono) · `next-themes` (light/dark).

## Develop

```bash
cd landing
pnpm install # standalone; resolves from the repo's pnpm store
pnpm dev # binds 0.0.0.0:3200 — http://localhost:3200 (and over the LAN)
```

> Port `3100` is taken by the `mission-control` container, so dev/start/serve
> default to **`3200`** on `0.0.0.0` (reachable from other machines on the LAN).
> Change the port in `package.json` if `3200` is occupied.

## Build & deploy

```bash
pnpm build # static export → ./out
pnpm serve # preview the exported site locally (npx serve)
```

`out/` is a plain static bundle. Drop it on GitHub Pages, S3/CloudFront,
Netlify, Vercel, or behind the same reverse proxy as the app. No Node server
is required. (If you later need server features, remove `output: "export"`
in `next.config.ts` and run `pnpm start`.)

Set the canonical URL via `NEXT_PUBLIC_SITE_URL` at build time (used for
metadata / Open Graph). Defaults to `https://forge.axiom-labs.dev`.

## Live data

**Version + changelog** are read from the repo **at build time** (`lib/releases.ts`):
the version comes from `../package.json` and the release list is parsed from the
real `../CHANGELOG.md` — so the site stays accurate on every rebuild, with a
baked-in real fallback if those files aren't found. No hard-coded version or
changelog copy to drift.

**Star count is live at runtime.** `components/github-stars.tsx` is a client
component that fetches `stargazers_count` from the public GitHub REST API (no
token; CORS-open) and renders a `★ N` badge in the nav + footer. It renders
nothing while loading or on error, dedupes concurrent mounts via a module-level
in-flight promise, and caches the count in `localStorage` for 1h to stay well
under the unauthenticated rate limit. Repo identity lives in the Node-free
`lib/repo.ts` so the client bundle never pulls `lib/releases.ts`'s build-time
`fs` reads.

## Layout

```
landing/
app/
layout.tsx # fonts, theme provider, metadata
page.tsx # the landing page (composes the sections below)
releases/page.tsx # /releases — full changelog
docs/page.tsx # /docs — docs index
globals.css # Forge tokens + motion + responsive layer
components/
icon.tsx # Forge icon set (stroke-1.6 lucide-style)
logo.tsx # the Forge brand mark (inline SVG)
primitives.tsx # Eyebrow, GhostButton, SectionShell
theme-toggle.tsx # nav light/dark toggle (client)
github-stars.tsx # live GitHub star badge (client; runtime fetch)
nav.tsx hero.tsx pillars.tsx runtimes.tsx product-strip.tsx
planning.tsx self-host.tsx releases-section.tsx footer.tsx docs-content.tsx
lib/
repo.ts # repo identity + GitHub endpoints (Node-free)
releases.ts # build-time version + changelog (../package.json, ../CHANGELOG.md)
```

## Design fidelity

The section components are inline-styled with `hsl(var(--token))` exactly as the
prototype. Production-only additions over the prototype:

- The canvas/tweaks shell is dropped; the page renders directly and **reflows
responsively** (the prototype shipped fixed desktop/mobile artboards).
- Responsive behaviour is layered via marker classes (`.lnd-cols-*`,
`.lnd-pad`, `.lnd-hero-grid`, `.lnd-nav*`, `.lnd-footer*`) in `globals.css`.
- Prototype hover handlers (`onMouseEnter`/`onMouseLeave`) became CSS `:hover`
classes so the components can stay server-rendered.
- A real light/dark **theme toggle** in the nav (the prototype's lived in the
design-canvas panel).
Binary file added landing/app/apple-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
41 changes: 41 additions & 0 deletions landing/app/docs/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { Metadata } from "next";
import { LandingNav } from "@/components/nav";

Check failure on line 2 in landing/app/docs/page.tsx

View workflow job for this annotation

GitHub Actions / Lint · Typecheck · Unit

Cannot find module '@/components/nav' or its corresponding type declarations.
import { LandingFooter } from "@/components/footer";

Check failure on line 3 in landing/app/docs/page.tsx

View workflow job for this annotation

GitHub Actions / Lint · Typecheck · Unit

Cannot find module '@/components/footer' or its corresponding type declarations.
import { DocsContent } from "@/components/docs-content";

Check failure on line 4 in landing/app/docs/page.tsx

View workflow job for this annotation

GitHub Actions / Lint · Typecheck · Unit

Cannot find module '@/components/docs-content' or its corresponding type declarations.

const DESCRIPTION =
"Everything you need to install Forge, connect an agent, and ship the first plan. Get started, runtimes & agents, and full reference.";

export const metadata: Metadata = {
title: "Docs",
description: DESCRIPTION,
alternates: { canonical: "/docs/" },
openGraph: {
type: "website",
siteName: "Forge",
url: "/docs/",
title: "Docs · Forge",
description: DESCRIPTION,
images: [{ url: "/opengraph-image", width: 1200, height: 630, alt: "Forge — issue tracking for humans & agents." }],
},
};

// Docs landing — ported from the prototype's DocsPage.
export default function DocsPage() {
return (
<div
style={{
background: "hsl(var(--background))",
color: "hsl(var(--foreground))",
fontFamily: "var(--font-sans)",
minHeight: "100%",
}}
>
<LandingNav />
<main>
<DocsContent />
</main>
<LandingFooter />
</div>
);
}
Loading
Loading