Badges and heads

The badge that cuts through the GT monograms after the Brand title, and the book head every hub page opens with, live at two widths.

Updated

Every page of the hub that reads as a book opens with the same head: the title, a lead of one to three lines, a panel of facts, and one hatch band. DESIGN.md section 4 sets the standard and pnpm lint:heads holds it. /brand alone sets a badge after its title, which cuts through the GT monograms one frame at a time.

The head badge

The plate sets the Brand title with its badge as BookHead sets it: the badge follows the title's last word and never breaks away from it. Count sets how many monograms the strip holds, and Size sets the title at the page and section steps. Still applies the rule reduced motion applies.

Every frame sits side by side in one strip, each exactly one box wide, and a CSS animation steps the strip one box to the left every 1.4 seconds with steps(n), so each change is a hard cut. A hidden sizer stacks every frame in one cell, so the box takes the widest frame's width and never changes size. BookHead hides the badge from the accessible name, so the h1 a crawler reads holds the title alone.

Import and props

import { BadgeCycle, badgeMark } from '@/components/viewer/BadgeCycle';

<BookHead badge={<BadgeCycle frames={files.map((file) => badgeMark(file))} />} />;
ExportPropsWhat it does
BadgeCycleframes: { key, content }[]The strip of frames. With no frames it renders nothing.
badgeMark(src)a public file pathOne frame that draws the file as an alpha mask in the title's ink.

The rules live in src/components/viewer/BookView.css, so a host outside a book head imports that sheet, as this plate does.

When to use it

Only /brand's head carries a badge (Kevin, 2026-10-21): the GT monogram, then the register's monograms. Every other book head sets its title alone, and pnpm lint:heads fails a badge outside src/app/brand.

Reduced motion and themes

Under reduced motion the strip stops on the first frame and the box takes that frame's width. The frames draw in the title's ink, so the badge follows the theme.

The book head

A page keeps one h1, so the plate shows the head in its own document: a live hub page in a frame, scaled to the plate. Page picks the route, and Width lays it out at 1440 or 390 pixels. The head is a container, so at the phone width the panel drops under the lead. The page inside stays live.

The frame follows the docs theme through the root layout's theme script, and it loads only when the plate comes near the viewport.

Import and props

import { BookHead } from '@/components/viewer/BookView';

<BookHead
  title={PAGE_NAMES.marks.name}
  lead='The speed set is seven General Translation marks in one register.'
  updated={updated}
  facts={[
    { icon: 'swatch', key: 'Marks', value: 9 },
    { icon: 'speed', key: 'Speed set', value: 7 },
    { icon: 'archive', key: 'Earlier round', value: 2 },
  ]}
/>;
PropTypeWhat it does
titlestringThe page's plain name from PAGE_NAMES, or a record's own title. It is the page's one h1.
badgenode/brand only: the badge after the title's last word, hidden from the accessible name.
leadnodeOne to three lines at the lead measure, 200 characters at most.
updatedPageUpdatedThe page's entry in src/lib/updated.ts, passed down from its server page.
factsthree facts, or one fact with installThe panel's rows after Updated, each { icon, key, value }.
installstringAn install command in a copy field, in place of the second and third facts.
notenodeThe rest of the introduction, under the mast's rule.
contentsnodeThe page's contents nav, left out on a page of fewer than two sections.

The server page calls requireUpdated('<route>') and passes the entry down, because a client module may not import src/lib/updated.ts. A new route also needs its paths in scripts/build/updated.mjs.

When to use it

Use BookHead on every hub page with a book head; a page differs from another only in its words and its facts. Pages outside the shell, such as these docs, the deck and the /d/ directions, have heads of their own.

Reduced motion and themes

The head itself does not move; its badge holds its first frame under reduced motion. Every value is a --pt- token, so the head follows the theme.

The head's numbers

The panel's column is 304 px (--pt-head-panel in src/components/viewer/tokens.css), sized for its longest value: a date with its hint, such as "Sep 10, 2026 4 weeks ago", which measures 168 px. The panel's rows sit on the lead's line pitch, 26.35 px, so a fact lines up with a line of the lead beside it. Pages and the viewer shell holds every number of the book page with what it measures.

On this page