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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
157 changes: 157 additions & 0 deletions archive/templates/galley/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# Galley — @inkform/theme-galley

Galley is Inkform's own design system, built on `@inkform/framework`. Warm
opaque paper + ink, one editorial "Proof" red-pencil accent, a serif prose
voice (Newsreader) beside a mono machine voice (JetBrains Mono) and a sans UI
voice (General Sans). Depth comes from paper layering and hairlines, never
heavy shadow or gradient. It supports Guides + API Reference tabs, plus Blog
and Changelog, out of the box.

---

## Run locally

```bash
npm install
npm run dev
# → http://localhost:3000
```

If this is a fresh clone, copy the env file first:

```bash
cp .env.example .env.local
# Edit NEXT_PUBLIC_SITE_URL if needed, then:
npm run dev
```

---

## Add content

All content lives in `content/docs/`.

### Navigation — `content/docs/docs.json`

`docs.json` controls the site name, logo, tabs, and page hierarchy:

```jsonc
{
"name": "Your Docs",
"tabs": [
{
"tab": "Guides",
"navigation": [
{
"group": "Get Started",
"pages": [
{ "title": "Introduction", "slug": "", "file": "index.mdx" },
{ "title": "Quickstart", "slug": "quickstart", "file": "quickstart.mdx" }
]
}
]
},
{ "tab": "API Reference", "openapi": "openapi.json" }
]
}
```

- `slug` is the URL path (empty string = the index `/`).
- `file` is the MDX file path relative to `content/docs/`.
- The `openapi` field on a tab points to a JSON/YAML spec file in `content/docs/`.

### Writing MDX

Add `.mdx` files under `content/docs/` and register them in `docs.json`.
Galley supports all built-in blocks: `<Note>`, `<Tip>`, `<Warning>`, `<Card>`,
`<CardGroup>`, `<Steps>`, `<Step>`, `<Tabs>`, `<Tab>`, `<CodeGroup>`,
`<Accordion>`, `<ParamField>`, `<Frame>`, and more.

### API Reference

Replace `content/docs/openapi.json` with your own OpenAPI 3.x spec (JSON or
YAML). The site auto-generates a sidebar and per-operation pages. No extra
configuration needed — just point the `openapi` tab field at your spec file.

### Blog and Changelog

Both ship wired and ready — `/blog` (list + post pages) and `/changelog`
(single dated list) render automatically once you add content:

```
content/
blog/
my-first-post.mdx # frontmatter: title, date, author, tags, description
series.json # optional — group posts into a series
changelog/
2026-01-15-v1.mdx # frontmatter: title, date, version
```

Both nav links only appear once at least one entry exists — an empty
`content/blog`/`content/changelog` (or no folder at all) keeps the top nav
clean and the pages still render a "no posts yet" state if visited directly.

---

## Maintain

### Slug redirects

When a page's URL changes, record the old → new slug mapping in
`content/docs/slug-history.json` to issue a 301 redirect:

```json
{
"old-page-slug": "new-page-slug",
"essentials/old-name": "essentials/new-name"
}
```

### Ask AI widget

The Ask AI button is built in but **disabled by default**. Enable it by setting
`NEXT_PUBLIC_DOCS_AI_ENABLED=true` in `.env.local`. Wire up a real LLM provider
in `app/api/ask/route.ts` (see the TODO comment there; currently returns a stub).

---

## Deploy to Vercel

1. Push this directory (or the whole monorepo) to a GitHub repository.
2. In the Vercel dashboard, click **Add New → Project** and import the repo.
3. **Framework preset**: Next.js.
4. **Root directory**: set to the path of this folder if deploying as a
standalone (e.g. `oss/templates/galley`), or leave blank if deploying the
directory itself.
5. Add the environment variable `NEXT_PUBLIC_SITE_URL` (your production URL,
e.g. `https://docs.example.com`).
6. Click **Deploy**.

For a custom domain, go to **Settings → Domains** in your Vercel project and add
your domain. Vercel handles SSL automatically.

---

## Deploy to AWS Amplify

1. Connect the repo in the Amplify console.
2. Set the **Build settings** manually if auto-detection picks the wrong preset:
- **Build command**: `npm ci && npm run build`
- **Output directory**: `.next`
- **Framework**: Next.js (SSR)
3. Add the `NEXT_PUBLIC_SITE_URL` environment variable under
**Environment variables**.
4. Deploy. Amplify Hosting supports Next.js SSR/ISR natively since Gen 2.

---

## Ask AI (deferred)

The `<AskAi />` widget in the top bar is built in. To activate it:

1. Set `NEXT_PUBLIC_DOCS_AI_ENABLED=true`.
2. Implement the LLM call in `app/api/ask/route.ts`.
3. Add `ANTHROPIC_API_KEY` (or your provider key) as a server-side env var.

The widget renders in both enabled and disabled states — it just shows an
informational notice when disabled.
59 changes: 59 additions & 0 deletions archive/templates/galley/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type { Metadata } from 'next';
import { Newsreader, JetBrains_Mono } from 'next/font/google';
import '@inkform/framework/styles.css';
import './theme.css';
import { themeInitScript } from '@inkform/framework/theme-toggle';
import { loadDocsConfig } from '@inkform/framework/content';

// Two-voice typography: Newsreader is the human/prose voice (display +
// long-form reading), General Sans is the UI voice (loaded via a <link> tag
// in <head> below — it's a Fontshare font, not on Google Fonts, so it can't
// go through next/font/google), JetBrains Mono is the machine voice (anything
// Git touches: paths, hashes, commits, code). Matches the Galley design
// system's own font stack exactly (see the inkform-design skill).
const newsreader = Newsreader({
subsets: ['latin'],
style: ['normal', 'italic'],
variable: '--font-heading',
display: 'swap',
});

const jetbrainsMono = JetBrains_Mono({
subsets: ['latin'],
variable: '--font-mono',
display: 'swap',
});

export async function generateMetadata(): Promise<Metadata> {
const config = loadDocsConfig();
const name = config?.name ?? 'Galley Docs';
return {
title: { default: name, template: `%s · ${name}` },
description: `Documentation for ${name}`,
icons: { icon: config?.favicon ?? '/favicon.svg' },
};
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html
lang="en"
className={`${newsreader.variable} ${jetbrainsMono.variable}`}
suppressHydrationWarning
>
<head>
{/* No-flash theme init — must run synchronously before first paint */}
<script dangerouslySetInnerHTML={{ __html: themeInitScript }} />
{/* General Sans — Fontshare (not on Google Fonts). See the
inkform-design skill's readme.md § Fonts: CDN for now, self-host
by dropping binaries in assets/fonts/ and swapping this for a
local @font-face rule. */}
<link
rel="stylesheet"
href="https://api.fontshare.com/v2/css?f[]=general-sans@200,300,400,500,600,700&display=swap"
/>
</head>
<body>{children}</body>
</html>
);
}
104 changes: 104 additions & 0 deletions archive/templates/galley/app/theme.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
* Galley theme — token overrides for @inkform/framework.
* This file is imported AFTER framework/styles.css so its declarations win.
* Only --fw-* tokens and small Galley-specific accents are set here.
* The framework's structural CSS is untouched.
*
* Identity: Inkform's own design system — a printer's galley. Warm opaque
* paper + ink, one editorial "Proof" red-pencil accent (#C24E3D, unchanged
* between light/dark). Depth from paper layering + hairlines, never heavy
* shadow or gradient. Values below are lifted directly from the
* `inkform-design` skill's tokens/{colors,effects,typography}.css — the
* authoritative source; do not hand-tune a value here without checking there
* first.
*/

/* ── Font variables ───────────────────────────────────────────────────────
--font-heading and --font-mono are set by next/font in layout.tsx. General
Sans has no next/font variable — it's a Fontshare font (loaded via a
<link> tag in layout.tsx's <head>), so it's named directly here. */
:root {
--fw-font: 'General Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--fw-font-heading: var(--font-heading, 'Newsreader', Georgia, 'Times New Roman', serif);
--fw-mono: var(--font-mono, ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, monospace);
}

/* ── Light mode (default) — paper: canvas → raised → well ───────────────── */
:root {
/* Surfaces */
--fw-bg: #fcfbf7;
--fw-bg-subtle: #f6f4ed;
--fw-fg: #191813;
--fw-muted: #8b8779;
--fw-border: #e4e0d4;
--fw-border-strong: #d8d3c5;
--fw-card: #f6f4ed;
--fw-card-hover: #efebe1;
--fw-code-bg: #efebe1;
--fw-kbd-bg: #efebe1;

/* Brand — the proof-red pencil accent */
--fw-primary: #c24e3d;
--fw-primary-fg: #fcfbf7;
--fw-primary-subtle: #f7e9e6;

/* Shape — Galley's card radius / control radius */
--fw-radius: 10px;
--fw-radius-sm: 6px;

/* Shadows — warm-tinted, low elevation, never heavy blur or hard-offset */
--fw-shadow: 0 1px 2px rgba(40, 30, 20, 0.05), 0 2px 4px rgba(40, 30, 20, 0.04);
--fw-shadow-lg: 0 4px 8px rgba(40, 30, 20, 0.06), 0 14px 34px rgba(40, 30, 20, 0.10);
--fw-ring: 0 0 0 3px #f7e9e6;

/* HTTP method pills — Galley's brand tokens don't define API-method colors
(out of brand scope), so these lean on the palette's own git-semantic +
warning hues rather than introducing cool blues that would clash with
the warm paper surface. */
--fw-method-get: #4c9a5c;
--fw-method-post: #c24e3d;
--fw-method-put: #a9762a;
--fw-method-patch: #8a5a78;
--fw-method-delete: #97392c;
--fw-method-head: #4f7a78;
--fw-method-options: #8b8779;
}

/* ── Dark mode — warm ink, never blue-grey ───────────────────────────────── */
html.dark {
--fw-bg: #131210;
--fw-bg-subtle: #1b1a17;
--fw-fg: #f2efe6;
--fw-muted: #7b776b;
--fw-border: #2f2d28;
--fw-border-strong: #3b3833;
--fw-card: #1b1a17;
--fw-card-hover: #242320;
--fw-code-bg: #242320;
--fw-kbd-bg: #242320;

/* Brand — Proof holds its value; only the tint deepens */
--fw-primary: #c24e3d;
--fw-primary-fg: #fcfbf7;
--fw-primary-subtle: #33201d;

/* Shadows on warm near-black */
--fw-shadow: 0 1px 2px rgba(0, 0, 0, 0.34), 0 2px 4px rgba(0, 0, 0, 0.28);
--fw-shadow-lg: 0 6px 14px rgba(0, 0, 0, 0.46), 0 18px 40px rgba(0, 0, 0, 0.52);
--fw-ring: 0 0 0 3px #33201d;

/* HTTP method pills — lifted for dark stock, same hue family as light */
--fw-method-get: #74be84;
--fw-method-post: #d6796b;
--fw-method-put: #d3a45e;
--fw-method-patch: #b586a8;
--fw-method-delete: #d98379;
--fw-method-head: #7fa8a6;
--fw-method-options: #aba79a;
}

/* Top bar (tabs/anchors/nav links/CTA/brand) is now styled by the shared
framework layer (packages/framework/src/styles/layout.css) — it only
ever consumed --fw-* tokens here, so there was nothing theme-specific
left to override for Galley. See Mono's theme.css for an example of a
theme that DOES need a delta on top of the shared base. */
45 changes: 45 additions & 0 deletions archive/templates/galley/content/docs/docs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"name": "Galley",
"version": "1.0.0",
"logo": "/logo.svg",
"favicon": "/favicon.svg",
"colors": { "primary": "#c24e3d" },
"navbarLinks": [
{ "name": "Support", "href": "mailto:support@example.com" }
],
"anchors": [
{ "name": "Documentation", "href": "/", "icon": "book" },
{ "name": "GitHub", "href": "https://github.com/inkform-dev/framework", "icon": "github" }
],
"cta": { "label": "Dashboard", "href": "https://example.com/dashboard" },
"tabs": [
{
"tab": "Guides",
"navigation": [
{
"group": "Get Started",
"pages": [
{ "title": "Introduction", "slug": "", "file": "index.mdx", "icon": "book-open" },
{ "title": "Quickstart", "slug": "quickstart", "file": "quickstart.mdx", "icon": "rocket" },
{ "title": "Development", "slug": "development", "file": "development.mdx", "icon": "terminal" }
]
},
{
"group": "Essentials",
"pages": [
{ "title": "Markdown Syntax", "slug": "essentials/markdown", "file": "essentials/markdown.mdx", "icon": "type" },
{ "title": "Code Blocks", "slug": "essentials/code-blocks", "file": "essentials/code-blocks.mdx", "icon": "code" },
{ "title": "Images & Embeds", "slug": "essentials/images", "file": "essentials/images.mdx", "icon": "image" },
{ "title": "Components", "slug": "essentials/components", "file": "essentials/components.mdx", "icon": "blocks" },
{ "title": "Navigation", "slug": "essentials/navigation", "file": "essentials/navigation.mdx", "icon": "map" }
]
}
]
},
{
"tab": "API Reference",
"openapi": "openapi.json",
"apiReference": { "renderer": "native" }
}
]
}
Loading
Loading