Skip to content

Commit 712361b

Browse files
docs(site): give the core narrative a front door on the home page — a Why link in the hero, '00 · The idea', a Why nav entry, the closing card trimmed (#22974)
Fixes #22951 Clause-②: no The home page now opens the same door the README and the docs do: the essay "The Ontology Is the Software" is reachable from the hero, from a new section 00 and from the top nav. The closing card loses the long-form line that used to be the page's only link to it. ## What changed Two files: `apps/docs/app/[lang]/page.tsx` and `apps/docs/lib/layout.shared.tsx`. 1. **Hero link.** Under the four-promise paragraph and above the button row: one text link, "Why the ontology is the software", with the arrow icon the page's other inline links use. No fifth button; the four buttons are untouched. 2. **`00 · The idea`**, between the hero and `01 · The loop`, in the 01–03 section shape (`border-t` rule, eyebrow in `--l-mono`, `h2` in `--l-display`). It holds `OntologyRunsFigure` imported from `@/components/figures` (not copied), the three sentences verbatim from the ruling, and "Read the essay" with the exact class string of "Browse the full vocabulary in the docs". Existing section numbers are unchanged. 3. **Top nav.** `{ text: 'Why', url: ESSAY_URL, active: 'url' }` before `Blog` in `baseOptions().links`. 4. **Closing card.** "Read the long form:" and its link are gone; the slogan sentence and the ObjectOS line stay as they were. The essay's route is one constant, `ESSAY_URL` in `lib/layout.shared.tsx`, read by the nav entry and by both page links. `HOME_TITLE`, `HOME_DESCRIPTION` and the metadata blocks are unchanged. ## Measured in the browser Production build served by `next start`, preinstalled Chromium, `/` in both themes at 1280 px and 390 px. In each of the four runs the `html` element carried the expected theme class, and `scrollWidth` equalled the viewport (no horizontal scroll). Light and dark measured the same sizes; the rows below differ only by width unless a theme is named. | | 1280 px | 390 px | |---|---|---| | Hero link | 251 × 24 px, centred, 20 px under the paragraph, 33 px above the buttons; 16 px, arrow present | 251 × 24 px, centred, same spacing | | Hero link contrast | light 18.2:1, dark 15.7:1 | same | | Section order | prose paragraph, then `00 · The idea`, then `01 · The loop` | same | | Section 00 type | eyebrow IBM Plex Mono, rule 1 px solid, h2 Bricolage Grotesque 36 px | h2 30 px | | Figure | wide drawing: SVG 846 × 341 px in an 896 × 391 px plate | stacked drawing: SVG 316 × 507 px in a 342 × 533 px plate | | Figure in each theme | SVG text near-black on the light plate, near-white on the dark one | same | | Caption | 14 px italic, 12 px above, muted, one line | two lines | | Three sentences | three columns, 347 px each, 18 px | stacked, 342 px each | | Read the essay | 121 × 20 px, 14 px, arrow | same | | Nav `Why` | in the bar at x = 170, before `Blog` at x = 222; 14 px, same colour as `Blog` | inside Toggle Menu: `Why` at y = 72 above `Blog` at y = 108; 16 px, foreground colour | | Closing card | no "Read the long form", zero links to the essay; its only link is "Try ObjectOS" | same | ## Gates All at head `011e8dfe` unless stated. - `pnpm turbo run build --filter=@objectstack/docs --concurrency=2`, the `buildCommand` in `apps/docs/vercel.json` that CI's Build Docs job runs, under `os-verify-lock`: `Tasks: 2 successful, 2 total`, `Cached: 0 cached, 2 total`, `.next/BUILD_ID` present, `VERDICT command-exit 0`. - `pnpm --filter @objectstack/docs build` under `os-verify-lock`, at `ba94665b` (the one later commit removes a single comment line): `VERDICT command-exit 0`. The tree was still clean after the generators ran. - `pnpm --filter @objectstack/docs typecheck`: `VERDICT command-exit 0`; `tsc --listFilesOnly` lists both touched files. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (change set from the merge base, 2 paths): 27 commands, every one run, every one exit 0. The `--ran` reconciliation reads `27 derived, 27 run, 0 NOT-MEASURED, 0 UNRUN`, with an exit code recorded for each. - eslint, narrowed to the two touched files. Both are in the population: `isPathIgnored` is false, and they fall under the config's `**/*.{ts,tsx,…}` block. With `--format json` it reports 2 files, 0 errors, 0 warnings. Neither file gets `parserOptions.project` or `projectService`, so linting is untyped and per-file, and this diff cannot change any other file's result. The repo-wide `pnpm lint` stays with CI. - Not measured locally, left to CI: the workspace-wide type-check lanes, and the roster and wide-population families that `dispatch-gates` lists outside its 27. Changeset: none. `apps/docs` is `private: true`, and nothing under `packages/**`, `content/**`, `README.md` or `apps/docs/public/**` changed (`git diff --name-only` over those paths from the base: 0), so this PR takes `skip-changeset`. ## Acceptance notes - **Section 00's heading and the figure caption are the essay's own words.** The ruling named the `h2` slot but not its text. "Why code recedes" is the essay's heading for the section this figure sits in, and the caption is the essay's own caption for this figure, verbatim. Either is a one-line swap if a different wording is wanted. - **The three sentences are the ruling's, verbatim.** They do not appear in the essay's text (zero hits under `content/`). - **The home page styles the figure's caption.** `Figure` gives its `figcaption` only `text-center italic` and takes spacing, size and colour from the blog's `prose` wrapper. The home page has no prose wrapper, so section 00's wrapper sets them (`[&_figcaption]:mt-3`, `text-sm`, `text-fd-muted-foreground`). Any later consumer outside `prose` will meet the same thing. - **In the production build, `Why` does not highlight on the essay's own page, and `Blog` does not highlight on any post.** Both configs are as ruled; the cause predates this PR. Blog posts are prerendered under the internal `/en/blog/SLUG` path (`.next/prerender-manifest.json`). The nav's active check compares each `url` against that path during prerender, and hydration does not repaint the attribute. `/blog` itself renders on demand and does highlight `Blog`. Measured on this branch's build: `data-active` is `false` for both items on `/blog/the-ontology-is-the-software` and on `/blog/context-window-is-the-constraint`, and `true` for `Blog` on `/blog`. The `Blog` line is unchanged by this diff. Reported to the seat; nothing is changed here. - **Light-mode nav contrast** is 4.35:1 at 14 px for both `Why` and `Blog` (the fumadocs nav token; dark 9.0:1). Unchanged here. - Screenshots were kept outside the worktree and are not committed. --- _Generated by [Claude Code](https://claude.ai/code/session_011hRnra93sK5Q2gTYYTbdJR)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent a2240c4 commit 712361b

2 files changed

Lines changed: 61 additions & 11 deletions

File tree

‎apps/docs/app/[lang]/page.tsx‎

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Link from 'next/link';
33
import { ArrowRight, Check } from 'lucide-react';
44
import { Bricolage_Grotesque, IBM_Plex_Mono } from 'next/font/google';
55
import { HomeLayout } from 'fumadocs-ui/layouts/home';
6-
import { baseOptions, gitConfig } from '@/lib/layout.shared';
6+
import { baseOptions, ESSAY_URL, gitConfig } from '@/lib/layout.shared';
77
import { absoluteUrl, HERO_COVER } from '@/lib/site';
88
import {
99
APACHE_2_0_URL,
@@ -16,6 +16,7 @@ import {
1616
type JsonLdNode,
1717
} from '@/lib/structured-data';
1818
import { YouTubeEmbed } from '@/components/youtube-embed';
19+
import { OntologyRunsFigure } from '@/components/figures';
1920

2021
/** The 90-second overview — the same video the README's hero cover links to. */
2122
const OVERVIEW_VIDEO_ID = 'CX_FlOoOtr0';
@@ -122,6 +123,13 @@ function homeGraph(): JsonLdNode[] {
122123
];
123124
}
124125

126+
/** Section 00's three sentences, verbatim from the maintainer's ruling. */
127+
const IDEA: string[] = [
128+
'An enterprise is definition plus execution. When execution is nearly free, it is its definition.',
129+
'What the model lacks is not intelligence: a world, hands, and a fence.',
130+
'An ontology written clearly enough is software. Models change; the ontology stays.',
131+
];
132+
125133
const VOCABULARY: { tag: string; title: string; copy: string }[] = [
126134
{ tag: 'object', title: 'Objects & fields', copy: 'Typed schemas with relations, validation, formulas, and files.' },
127135
{ tag: 'permission', title: 'Permissions', copy: 'RBAC plus row- and field-level security, enforced by the runtime.' },
@@ -223,6 +231,15 @@ export default function HomePage() {
223231
metadata small enough for AI to hold whole: agents read it whole, reason it whole,
224232
refactor it whole.
225233
</p>
234+
<p className="mt-5">
235+
<Link
236+
href={ESSAY_URL}
237+
className="inline-flex items-center gap-1 font-medium text-fd-foreground underline underline-offset-4 transition-colors hover:text-fd-primary"
238+
>
239+
Why the ontology is the software
240+
<ArrowRight className="size-4" />
241+
</Link>
242+
</p>
226243
<div className="mt-8 flex flex-wrap items-center justify-center gap-3">
227244
<Link
228245
href="/docs/getting-started"
@@ -306,6 +323,40 @@ export default function HomePage() {
306323
</p>
307324
</section>
308325

326+
{/* ── 00 · the idea ────────────────────────────────────── */}
327+
<section className="relative mx-auto w-full max-w-6xl px-6 py-16 md:py-20">
328+
<div className="flex items-baseline gap-4 border-t border-fd-border pt-8">
329+
<span className="text-xs tracking-[0.18em] text-fd-muted-foreground uppercase" style={{ fontFamily: 'var(--l-mono)' }}>
330+
00 · The idea
331+
</span>
332+
</div>
333+
<h2 className="mt-4 max-w-2xl text-3xl font-bold tracking-tight md:text-4xl" style={{ fontFamily: 'var(--l-display)' }}>
334+
An ontology written clearly enough runs directly
335+
</h2>
336+
{/* The figure's caption takes its spacing and colour from the blog's prose
337+
styles there; this page has no prose wrapper, so the wrapper sets them. */}
338+
<div className="mx-auto mt-10 max-w-4xl [&_figcaption]:mt-3 [&_figcaption]:text-sm [&_figcaption]:text-fd-muted-foreground">
339+
<OntologyRunsFigure caption="The ontology is not the design document for the software; the runtime runs it directly." />
340+
</div>
341+
<div className="mt-10 grid gap-8 md:grid-cols-3">
342+
{IDEA.map((line) => (
343+
<div key={line}>
344+
<div className="h-px bg-fd-border" aria-hidden />
345+
<p className="mt-4 text-lg font-semibold text-pretty" style={{ fontFamily: 'var(--l-display)' }}>
346+
{line}
347+
</p>
348+
</div>
349+
))}
350+
</div>
351+
<Link
352+
href={ESSAY_URL}
353+
className="mt-8 inline-flex items-center gap-2 text-sm font-medium underline underline-offset-4 transition-colors hover:text-fd-primary"
354+
>
355+
Read the essay
356+
<ArrowRight className="size-4" />
357+
</Link>
358+
</section>
359+
309360
{/* ── 01 · the loop ────────────────────────────────────── */}
310361
<section className="relative mx-auto w-full max-w-6xl px-6 py-16 md:py-20">
311362
<div className="flex items-baseline gap-4 border-t border-fd-border pt-8">
@@ -455,14 +506,7 @@ export default function HomePage() {
455506
The ontology is the software. Your objects, relations, actions, permissions, and
456507
flows are your business ontology — views, dashboards, apps, and translations are
457508
projections of it, and the definition layer of the AI era should be an open
458-
protocol you own. Read the long form:{' '}
459-
<Link
460-
href="/blog/the-ontology-is-the-software"
461-
className="inline-flex items-center gap-1 font-medium text-fd-foreground underline underline-offset-4 transition-colors hover:text-fd-primary"
462-
>
463-
The Ontology Is the Software
464-
<ArrowRight className="size-3.5" />
465-
</Link>
509+
protocol you own.
466510
</p>
467511
<p className="mt-3 text-sm text-fd-muted-foreground">
468512
ObjectStack is build &amp; ask with Claude Code. Rather build &amp; ask online —

‎apps/docs/lib/layout.shared.tsx‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ export const gitConfig = {
1212
branch: 'main',
1313
};
1414

15+
/** The essay's route: the nav's `Why` entry, and the home page's hero link and section 00. */
16+
export const ESSAY_URL = '/blog/the-ontology-is-the-software';
17+
1518
export function baseOptions(): BaseLayoutProps {
1619
return {
1720
nav: {
@@ -24,8 +27,11 @@ export function baseOptions(): BaseLayoutProps {
2427
),
2528
},
2629
// Every layout spreads baseOptions() — DocsLayout (docs sidebar), and HomeLayout on
27-
// the home page and on /blog — so this one entry is the blog's link on all of them.
28-
links: [{ text: 'Blog', url: '/blog', active: 'nested-url' }],
30+
// the home page and on /blog — so these entries are the nav's links on all of them.
31+
links: [
32+
{ text: 'Why', url: ESSAY_URL, active: 'url' },
33+
{ text: 'Blog', url: '/blog', active: 'nested-url' },
34+
],
2935
githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
3036
};
3137
}

0 commit comments

Comments
 (0)