hraness

a /design gallery that is the spec: generated, checked, always current

the executable component specification

Drafted by an AI agent at Ben Guo's direct request from the Hraness source repositories, and checked against those sources before publication.

Design documentation has a half-life. A components page written in a doc format is correct on the day it is written and quietly wrong ever after: a prop is renamed, a token is revalued, a state is added, and the screenshot still shows the old thing. The usual fixes, review checklists and screenshot regen days, fight the drift with effort, which is why the drift usually wins.

The Hraness answer is to stop maintaining a description of the design system and start maintaining the design system as something executable. Every registered product serves the same /design route, and that route renders one component, DesignSystemGallery, from the shared kit. The page is the spec. If a component changes, the gallery changes with it in the same build, and the checkers make sure the page exists and exercises what it claims. This lesson covers what the gallery is, what it must contain, and how it stays honest; the gated half goes into the verification machinery that makes “the spec” an enforceable claim.

the spec is a page

A specification is only useful if it cannot drift from the thing it describes. Prose documentation fails that test because it describes the component in a different medium; there is no mechanism that forces the words to change when the code does. An executable gallery passes it by construction: the gallery is the components, mounted and rendered, so the spec cannot be stale unless the components are.

That reframes what the page is for. /design is not marketing and not documentation for readers; it is a contract surface for builders, including agents. An agent that wants to know what the shared Button looks like in its disabled state, or whether the chart family supports a dark surface, does not read a wiki; it loads the route on a running product and observes the real thing.

one component, every product

The rule is uniform: every registered browser product mounts the same gallery at /design. On this site the rendered route is a few lines:

import { DesignSystemGallery } from "@jungle/design-kit/react";

export default function DesignPage() {
  return (
    <main>
      <DesignSystemGallery isNestedInMain />
    </main>
  );
}

Two details carry the contract. The import comes through @jungle/design-kit/react, the facade, so product code never reaches around the package boundary to a private copy. And the component is rendered directly rather than wrapped in product chrome, because a gallery that products could restyle would stop being a shared spec. The page’s exported metadata sets robots to index: false, follow: false: the route exists to be used and checked, not to be found. isNestedInMain is the only concession, telling the gallery it lives inside the site’s <main> landmark rather than owning the page itself.

Because the same component ships to every product, “the design system” stops being a claim about consistency and becomes a literal fact: there is one gallery, and hraness.com, sound.fish, and the rest all serve it.

Inside the kit, src/react/design-gallery.tsx registers the coverage as data. designGallerySections enumerates the surfaces the page must contain: foundation, paper-theme, lantern, marketing, shells, data, effects, and syntax. designGalleryTouchKinds names the interaction primitives under test, button, link, radio, range. designGalleryRecipeCoverage goes wider, asserting coverage across @hraness/ui primitives, application shells, charts, the chat message and composer, the dither and foil card surfaces, layout surfaces, the Lantern material, the playback transport, the plain-site and product-marketing grammars, Nebula Sans typography, procedural effects, and the production preview notice.

The point of registering coverage as constants rather than as prose is that “does the gallery cover X” is a question a check can answer. A new component family that ships without gallery coverage is not a doc gap; it is a missing entry in a checked registry.

the static lane

The first enforcement layer never opens a browser. scripts/check-design-system.ts in the monorepo scans product source for the violations that would quietly break the shared spec, and the /design route is one of its subjects. The checks that matter for the gallery are about custody: the route must import the gallery through the facade rather than a private path, and it must render the component directly rather than wrapping it, replacing it, or hiding it behind product markup.

The same checker enforces the surrounding style boundary that keeps the gallery meaningful. Product CSS may not select Jelly custom-element tags or reach inside a shared host’s internals, may not redefine the shared radius roles (--jelly-radius-compact, --jelly-radius-control, --jelly-radius-card, --jelly-radius-overlay), and may not paint opaque resting backgrounds on the shared semantic control classes (jungle-button__control, jungle-icon-button__control, jungle-segmented-control__item, and the rest of the checked list). The reason these rules sit beside the gallery contract is that a gallery is only a spec if the product cannot locally override what it shows. A /design page that renders one thing while the product’s own buttons are privately repainted is documentation again, with the same drift problem.

The static lane is cheap enough to run on every edit, which is the point: the cascade rules are enforced at the speed of a lint rather than the speed of a browser run, so the boundary failures never reach the browser lane at all.

the browser matrix

The second layer runs the real gallery in a real browser. bun run verify:design-system (with bun run verify:design-system:uncoordinated as the ungated backing script) drives scripts/verify-design-system.ts, which walks a checked registry of design surfaces. design-browser-surfaces.json declares hraness as the fullMatrixProject, meaning this site is the reference run that exercises every registered viewport and stress mode rather than a subset.

The matrix is concrete. The configured viewports are compact 320 × 568, mobile 390 × 844, tablet 768 × 1024, and desktop 1280 × 900. The stress modes push the surfaces out of their happy path: light, dark, 200-percent text, forced colors, coarse pointer, and reduced motion. A component that only works at default settings fails here the way a silent metadataBase fails a crawler: quietly, and at the boundary a real user or a real assistive technology occupies.

The verifier’s job is to make the gallery’s coverage claims observable. It is one thing to register that the data section exists; it is another to prove the charts render at 320 pixels wide under forced colors. Because /design is a registered surface in the matrix, the spec is exercised continuously rather than admired occasionally.

The stress list is worth reading as a statement of who the spec is for. 200-percent text is the user who has set a large default font size. Forced colors is the Windows contrast user whose palette overrides the author’s. Coarse pointer is the phone or tablet that needs the raised --interactive-target-min floor. Reduced motion is the user for whom a looping decorative effect is a vestibular problem. Each mode is a real person’s environment, and the matrix exists so that “it looked fine to me” is never the spec’s last word.

the edit contract

The last piece is a rule about change. The design-system runbook treats a component change and its gallery coverage as one edit: you do not ship a new primitive, a new state, or a new recipe without updating the gallery in the same change. That is the rule that keeps the executable spec executable; a gallery updated “later” is a gallery that drifts.

There is one honest exception worth naming. Sleepyland keeps its own intentionally local /design gallery rather than mounting the shared kit, a deliberate boundary documented in its repository: the studio preserves its local audio engine and visual system, and importing @hraness/ui or @hraness/design-kit would need a concrete cross-product consumer to justify it. The contract is not “every page must be identical”; it is “every product’s gallery must come from the package that owns it, be rendered directly, and be checked.” Sleepyland’s gallery is product-owned by design, and its checker still treats it as a spec surface.

Put together, the gallery works because three things are true at once: the page is the same component everywhere, the coverage is registered as data, and both a static and a browser check run against it. The spec cannot drift far, because drift is a build failure before it is a lie.

sources

  • design-kit: src/react/design-gallery.tsx for DesignSystemGallery, designGallerySections, designGalleryTouchKinds, and designGalleryRecipeCoverage.
  • The monorepo behind this site (projects): app/design/page.tsx for the direct mount and noindex metadata, scripts/check-design-system.ts and scripts/verify-design-system.ts for the two enforcement lanes, and design-browser-surfaces.json for the registered matrix.
  • sleepyland: the product-owned /design gallery and the boundary that keeps it local.
  • ui: the primitives the gallery exercises.

keep reading: free for subscribers

the rest of this lesson is free. add your email once and every subscriber lesson on this site stays unlocked.

already subscribed? enter the same email to unlock.