# The component library

> Prototemplate's live component library: every instrument mounted on its page with controls, its import path, its props and its reduced-motion still.

URL: https://www.prototemplate.com/docs/components

These pages mount the real components of the hub: the dithered fields, the light fields, the glyph rain, the doubled line, the isometric kit, the globes, the locale chips, the moving text, the marks and the heads. Every plate is the component itself, running, with controls for its props. Each section gives the import path, the props, when to use the component and what it does under reduced motion. The plate below is the studio field, the dithered material of the landing hero, with its ten presets.

<StudioFieldDemo />

## The pages [#the-pages]

The pages sit in ten groups, as the sidebar shows them: the instruments first (fields, the dither lab, drawings, 2D and 3D), then the pieces a reader handles (interactables, language and motion, marks and heads), then what the system makes and where it puts it (artifacts, page layouts, pages). Each card names the components its page mounts.

### Fields [#fields]

<Cards>
  <Card title="Dither and the studio field" href="/docs/components/dither" description="The ordered Bayer screens, the CPU dither loop and its field factories, the ten studio field presets." />

  <Card title="Horizon and prismatic fields" href="/docs/components/fields" description="The event-horizon shader and the prismatic burst, with their cursor effects." />

  <Card title="Glyph field and ink field" href="/docs/components/glyph-field" description="The eight-script glyph rain, the ink field and its pointer play." />
</Cards>

### Dither lab [#dither-lab]

<Cards>
  <Card title="The dither lab" href="/docs/components/dither-lab" description="Ordered dither, error diffusion and halftone side by side on pictures, gradients and noise, or a picture you drop in." />

  <Card title="Dithered type and marks" href="/docs/components/dither-type" description="Words and marks set in dither cells, a mark that erodes and resolves, and a screen of characters." />

  <Card title="Dithered transitions and brushes" href="/docs/components/dither-motion" description="Tone-mix wipes on one grid, a lens under the pointer and a brush that paints in cells." />
</Cards>

### Drawings [#drawings]

<Cards>
  <Card title="Doubled lines and connectors" href="/docs/components/lines" description="DoubledLine with its pulse, and TranslationFlow, the connector in production." />

  <Card title="Isometric drawings" href="/docs/components/iso" description="The isometric kit: boxes, prisms, faces and a seated mark, with the numbers that make separate drawings one set." />

  <Card title="Globes and maps" href="/docs/components/globes" description="EdgeGlobe, the dithered globe field, the blog globe figures in all three rounds." />

  <Card title="The blog globe figure" href="/docs/components/blog-globe" description="Four directions for a blog figure that turns a globe along the path of Euclid's Elements, with all three rounds live and their ranking." />
</Cards>

### 2D and 3D [#2d-and-3d]

<Cards>
  <Card title="3D scenes" href="/docs/components/three-scenes" description="three.js scenes through a Bayer post pass: an extruded GT mark, a lit globe and an isometric stack." />

  <Card title="2D canvas pieces" href="/docs/components/canvas-2d" description="Particle fields, generative lines and glyph rain on canvas 2D, each with its frame budget." />
</Cards>

### Interactables [#interactables]

<Cards>
  <Card title="Controls" href="/docs/components/controls" description="Segmented switches, toggles, sliders, steppers, the install field and copy buttons, with every state." />

  <Card title="Search, filters and menus" href="/docs/components/navigation" description="The command search, the list filter, the language selector, the help card and the toast." />

  <Card title="Kinetic text and carousels" href="/docs/components/kinetic" description="Split-flap text, the language wheel and the carousel, with their timing and stills." />
</Cards>

### Language and motion [#language-and-motion]

<Cards>
  <Card title="Locale tags and language pieces" href="/docs/components/language" description="LocaleTag against LocaleFlag, and the seven language diagrams." />

  <Card title="Reveal seam and sentence motion" href="/docs/components/motion" description="RevealSeam and EverySentence." />
</Cards>

### Marks and heads [#marks-and-heads]

<Cards>
  <Card title="Speed marks and the GT mark" href="/docs/components/marks" description="The speed marks and the globe concepts, GtWord and gtText(), DitheredMark." />

  <Card title="Badges and heads" href="/docs/components/heads" description="BadgeCycle, badgeMark() and BookHead." />
</Cards>

### Artifacts [#artifacts]

<Cards>
  <Card title="Live artifact pictures" href="/docs/components/artifact-pictures" description="Dithered photographs under the Blue Marble standard, screened live from their tone grids." />

  <Card title="Covers and social cards" href="/docs/components/covers-and-cards" description="Post covers, social cards and banners generated from a title and a field at their export sizes." />

  <Card title="Films and contact sheets" href="/docs/components/films-and-sheets" description="The film player, scrubbable contact sheets and the report card." />
</Cards>

### Page layouts [#page-layouts]

<Cards>
  <Card title="Rails, bands and spacers" href="/docs/components/rails-and-bands" description="The landing grammar as parts: a page skeleton built from bands at any width from 390 to 1440." />

  <Card title="Grids and bentos" href="/docs/components/grids-and-bentos" description="Bento and feature grids with columns, gaps and spans to adjust, lines drawn once at each junction." />

  <Card title="Shells and frames" href="/docs/components/shells" description="The viewer shell, the sheet frame and the plate, taken apart region by region." />
</Cards>

### Pages [#pages]

<Cards>
  <Card title="Page gallery" href="/docs/components/page-gallery" description="Every shipped page live in a frame at the desktop and the phone width, in both themes." />

  <Card title="Page templates" href="/docs/components/page-templates" description="The book page, the docs page, the article and the error page, each with an anatomy overlay." />
</Cards>

## Every component [#every-component]

| Component                                  | File                                                                     | Client                | Page                                        |
| ------------------------------------------ | ------------------------------------------------------------------------ | --------------------- | ------------------------------------------- |
| `createDitherLoop` and the field factories | `src/lib/dither.ts`                                                      | yes                   | [Dither](https://www.prototemplate.com/docs/components/dither)           |
| `BAYER_8`, `BAYER4`                        | `src/lib/dither.ts`, `src/app/d/toolchain/diagrams/DitheredMark.tsx`     | no                    | [Dither](https://www.prototemplate.com/docs/components/dither)           |
| `StudioField`, `createStudioField`         | `src/components/shared/StudioField.tsx`, `src/lib/studio-field.ts`       | yes                   | [Dither](https://www.prototemplate.com/docs/components/dither)           |
| `createHorizonField`                       | `src/lib/horizon-field.ts`                                               | yes                   | [Fields](https://www.prototemplate.com/docs/components/fields)           |
| `PrismaticField`, `createPrismaticField`   | `src/components/shared/PrismaticField.tsx`, `src/lib/prismatic-field.ts` | yes                   | [Fields](https://www.prototemplate.com/docs/components/fields)           |
| `createGlyphField`                         | `src/lib/glyph-field.ts`                                                 | yes                   | [Glyph field](https://www.prototemplate.com/docs/components/glyph-field) |
| `createInkField`                           | `src/app/d/glyph-rain/sections/band/inkField.ts`                         | yes                   | [Glyph field](https://www.prototemplate.com/docs/components/glyph-field) |
| `DoubledLine`                              | `src/components/shared/diagrams/DoubledLine.tsx`                         | no                    | [Lines](https://www.prototemplate.com/docs/components/lines)             |
| `TranslationFlow`                          | `src/app/d/toolchain/diagrams/TranslationFlow.tsx`                       | yes                   | [Lines](https://www.prototemplate.com/docs/components/lines)             |
| The isometric kit, `IsoFrame`              | `src/app/d/toolchain/diagrams/iso.ts`, `IsoFrame.tsx`                    | no                    | [Isometric](https://www.prototemplate.com/docs/components/iso)           |
| `EdgeGlobe`                                | `src/app/d/toolchain/diagrams/EdgeGlobe.tsx`                             | yes                   | [Globes](https://www.prototemplate.com/docs/components/globes)           |
| `globe()`                                  | `src/lib/dither.ts`                                                      | yes                   | [Globes](https://www.prototemplate.com/docs/components/globes)           |
| `GlobeFrame`                               | `src/components/blog-globe/GlobeFrame.tsx`                               | yes                   | [Globes](https://www.prototemplate.com/docs/components/globes)           |
| `LocaleTag`                                | `src/app/d/toolchain/components/LocaleTag.tsx`                           | no                    | [Language](https://www.prototemplate.com/docs/components/language)       |
| `LocaleFlag`                               | `src/components/shared/LocaleFlag.tsx`                                   | no                    | [Language](https://www.prototemplate.com/docs/components/language)       |
| The language diagrams                      | `src/app/d/toolchain/diagrams/lang/`                                     | yes                   | [Language](https://www.prototemplate.com/docs/components/language)       |
| `RevealSeam`                               | `src/app/d/toolchain/sections/RevealSeam.tsx`                            | yes                   | [Motion](https://www.prototemplate.com/docs/components/motion)           |
| `EverySentence`                            | `src/components/shared/EverySentence.tsx`                                | yes                   | [Motion](https://www.prototemplate.com/docs/components/motion)           |
| `MARKS`, `GLOBE_CONCEPTS`                  | `src/lib/marks.ts`, `public/marks/`                                      | no                    | [Marks](https://www.prototemplate.com/docs/components/marks)             |
| `GtWord`, `gtText`, `GtMark`               | `src/components/viewer/GtWord.tsx`, `src/components/viewer/GtMark.tsx`   | no                    | [Marks](https://www.prototemplate.com/docs/components/marks)             |
| `DitheredMark`                             | `src/app/d/toolchain/diagrams/DitheredMark.tsx`                          | no, the host animates | [Marks](https://www.prototemplate.com/docs/components/marks)             |
| `BadgeCycle`, `badgeMark`                  | `src/components/viewer/BadgeCycle.tsx`                                   | no                    | [Heads](https://www.prototemplate.com/docs/components/heads)             |
| `BookHead`                                 | `src/components/viewer/BookView.tsx`                                     | yes                   | [Heads](https://www.prototemplate.com/docs/components/heads)             |

Client means the module is a `'use client'` component or a canvas engine that needs the DOM. The rest render on the server and ship no JavaScript of their own. Several components live in `src/app/d/toolchain`, the direction that the later directions fork. The radius, type and oxlint gates skip that folder, and the site imports the components from there.

## The lifecycle every instrument keeps [#the-lifecycle-every-instrument-keeps]

1. **Mount late.** A canvas or WebGL engine starts when its plate comes within 180 pixels of the viewport, through one IntersectionObserver that disconnects after it fires.
2. **Pause when unseen.** From then on the engine pauses itself when it leaves the viewport and when the tab is hidden.
3. **Draw one still under reduced motion.** With `prefers-reduced-motion: reduce` an engine draws one designed frame and schedules no animation frames. A Still control on a plate shows that frame without changing the system setting.
4. **Release on unmount.** `destroy()` disconnects every observer and listener. The WebGL contexts of the studio, horizon and prismatic fields persist for the session, one per engine, because a context per mount exhausts the browser's budget.
5. **Follow the theme.** The theme is `html[data-theme]`. An engine reads its ink from a custom property and reads it again when the attribute changes; an SVG drawing reads `currentColor` and the tokens.

The fields tuned to an ink ground, the studio, horizon, prismatic and ink fields, sit on an ink plate in both themes. Everything else follows the docs theme.

### The numbers behind it [#the-numbers-behind-it]

The browser keeps a fixed budget of live WebGL contexts, and a page that runs past it gets a black canvas and no error in the console. The lifecycle above keeps every page inside that budget, and these numbers set it.

| Number                        | Value                        | What it decides                                                                                                                                                                                                                                                                                                                                                                              | Where it is held                                                                                                                                                                                  |
| ----------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Live WebGL contexts in Chrome | about 16                     | Past the budget `getContext` returns null and a field draws black. On 2026-07-29 a direction's shader rendered on a fresh load and was black after 12 client-side switches between directions.                                                                                                                                                                                               | One module-level engine per engine type, each drawing into one offscreen GL canvas and blitting into every mount's 2D canvas: `src/lib/studio-field.ts`, `horizon-field.ts`, `prismatic-field.ts` |
| Contexts per engine module    | 1 for the session            | The context survives a mount's `destroy()`, so route changes never create another.                                                                                                                                                                                                                                                                                                           | The same three modules                                                                                                                                                                            |
| Contexts a probe may create   | 0                            | A probe that calls `getContext` on the page's canvases to count them creates contexts and exhausts the budget it measures.                                                                                                                                                                                                                                                                   | Wrap `getContext` before the page's scripts run, or screenshot after real navigation                                                                                                              |
| Contexts a component may leak | 0                            | A component that owns its context deletes its buffer, its program and both shaders, then calls `WEBGL_lose_context.loseContext()` on unmount. A footer mark that skipped this leaked one context per mount (2026-08-08).                                                                                                                                                                     | The component's own cleanup                                                                                                                                                                       |
| Arm margin                    | 180 px                       | A lazy plate mounts its engine when it first comes within 180 px of the viewport. A plate the reader never scrolls near never starts its engine.                                                                                                                                                                                                                                             | `rootMargin: '180px'` in `src/components/docs/demos/hooks.ts`                                                                                                                                     |
| Live previews on one page     | stills until hover           | 22 live iframes running shaders made the presenter wall lag (2026-07-31). A gallery that froze each frame 2.8 s after load still held 12 live pages, 4 WebGL contexts and about 1.3 GB of renderer memory, and stayed busy about 950 ms of every second at rest (2026-10-08). A frozen same-origin frame still hydrates, composites and runs its CSS animations on the parent's main thread. | `src/app/present/viewer/LazyFrame.tsx` shows a thumbnail and mounts the live page only while a mouse is over the card                                                                             |
| An off-screen live stage      | about 110 ms of every second | The presenter's live prototype stage cost that much through the slides before it, so it is frozen whenever no part of its section is on screen.                                                                                                                                                                                                                                              | The rAF gate in `src/app/layout.tsx`, driven by `postMessage({ type: 'gt:freeze', frozen })`                                                                                                      |

The rAF gate wraps `requestAnimationFrame` only, so a loop on `setInterval` or `setTimeout` keeps running inside a frozen preview. [Canvas and WebGL engines](https://www.prototemplate.com/docs/engineering/engines#the-context-budget) explains each of these with the shared canvas that only grows, the readback canvases, zoom and the quality governor.

## Mounting a component in a docs page [#mounting-a-component-in-a-docs-page]

A docs page imports a component at the top of its MDX file and renders it as JSX. The page and its MDX are server components, so a component with state, a canvas or GSAP must be a `'use client'` module. fumadocs-mdx imports every docs page into the one `/docs/[[...slug]]` route, so a plate imported directly would put its code and its stylesheets into every docs page's first load. The pages therefore import their plates from `src/components/docs/demos/lazy.tsx`, which wraps each one in `next/dynamic`: the server still renders the plate, and its chunk and CSS load only on the page that shows it.

```mdx
import { StudioFieldDemo } from '@/components/docs/demos/lazy';

The plate runs the studio field with its ten presets.

<StudioFieldDemo />
```

Put a sentence beside every plate that says what it shows. The Markdown twin of the page and `/llms-full.txt` drop the import and keep the plate as a bare tag, such as `<StudioFieldDemo />`, so the sentence is what a reader of the twin gets.

The plates on these pages are built from one small kit in `src/components/docs/demos/`:

| Part                                                                 | What it does                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Plate`                                                              | The card: the stage, the entry point's name in its corner, and the controls row. `night` pins the stage to ink, `lazy` mounts the children when the plate nears the viewport, `fit` takes the content's height, and `moves` adds the reduced-motion note. |
| `Choice`, `Range`, `Toggle`, `Action`                                | The controls: a radio group drawn as a segmented row, a range with its value, a pressed button and a plain button.                                                                                                                                        |
| `useArmed`, `useReducedMotion`, `useTheme`, `readToken`, `useReplay` | The lifecycle hooks behind the list above.                                                                                                                                                                                                                |
| `lazy.tsx`                                                           | Every plate wrapped in `next/dynamic`, with a fallback at about the plate's height for a client navigation. A new plate gets its line here.                                                                                                               |

## The build log [#the-build-log]

The handbook's Libraries document indexes the same instruments and ends with the build log, where every library runs with its plates and API snippets.

<Cards>
  <Card title="Libraries" href="/docs/handbook/libraries" description="The index of the componentized instruments, then the build log: every library running live with its plates and API snippets." />
</Cards>

---

The index of every page on this site, for agents: https://www.prototemplate.com/llms.txt
