Skip to content

Search

Page layout

Page is the frame for a single-page app: a site bar with the author and a theme toggle, a header, your content, and a footer. Once the bar scrolls away, a compact one slides in with a reading-progress line.

<Page
eyebrow="@bhodgson/image-tagger"
project="image-tagger"
title={
<>
Tag <Highlight>images</Highlight> from your own vocabulary
</>
}
description="Define tags, then tag the samples or your own images."
actions={<Link href="https://github.com/bhodgs/image-tagger">Source</Link>}
>
<Panel id="vocabulary" title="Vocabulary">
…
</Panel>
</Page>

Panel is a window: a title bar over its content, with optional actions on the right. Its id makes the title a link target.

See the image-tagger playground for both in use.

Page heads its content with a PageHeader: an eyebrow, the title, a description and actions, marked with an accent bar. Use one on its own for pages you lay out yourself; it leaves the width and spacing around it to you. Long titles balance their lines, and descriptions avoid a last line of one word.

<PageHeader
eyebrow="private"
title="Contact"
description="Questions about a project, or about a role?"
/>

Page closes with a Footer. Use one on its own for pages you lay out yourself: your content on the left, and links on the right. Copyright reads “© 2026 Ben Hodgson · GitHub”, for a personal site where “a Ben Hodgson project” would repeat itself.

<Footer
links={[
{ label: "home", href: "/" },
{ label: "contact", href: "/contact/" },
]}
>
<Copyright />
</Footer>

TerminalLink to this section

A window whose title bar is a shell prompt, with the command’s output inside, for short facts like contact details.

<Terminal command="cat contact">
<dl>…</dl>
</Terminal>

Text haloLink to this section

text-halo gives text a halo in the canvas colour, so it stays readable over a drawing or the grid behind it.

SheetLink to this section

sheetClass is a quieter window, for each section of a long page: an outline and a surface to read on, without a Panel’s title bar or shadow, so the page’s header still leads. Space sheets from the outside, with the page’s own classes:

---
import { sheetClass } from "@bhodgson/design-system";
---
<div class="space-y-8">
<section class={sheetClass}>…</section>
<section class={sheetClass}>…</section>
</div>

ClearingLink to this section

bg-clearing puts a clear patch of canvas behind text, fading out into the grid on every side, so the grid’s lines don’t run through what’s being read. Its edge is a shadow, so it reaches past the text without moving it or widening the page. Use it on a column of text that sits straight on the grid; text-halo is enough for a line or two.

<div class="max-w-2xl bg-clearing">
<article>
<Content components={markdown} />
</article>
</div>

design-system is a Ben Hodgson projectGitHub