---
name: component-documentation
description: Research, write or review Ghost UI component documentation and copyable examples for designers, PMs and developers. Covers section decisions, public anatomy, example selection and source accuracy; not internal task reports.
---

# Component documentation

Help a reader choose, try, install and adapt the component. Start with a useful result; reveal the code and deeper contract as needed. Respect readers' intelligence without assuming React vocabulary. Explain a new term once or link its definition. Use the same name for the same thing.

Read canonical TSX/CSS, direct demos and registry/package metadata before drafting. Record actual parts, values/defaults, state ownership, dependencies and the closest alternatives. A competing library is research, not evidence that Ghost supports its props. Follow [the section guide](#sections) and [the editing guide](#writing).

Use the accepted order: **Preview → Design guidance (if useful) → Installation → Basic usage → Structures → Examples → API reference**. These sections serve different questions; don't repeat the same paragraph in each. Preserve useful existing anchors, including aliases when a heading changes. Use existing Preview, RegistryInstall, CodeBlock, Structure and ApiTable owners.

- Preview: one recognizable task with the real component. See [preview craft](#preview-craft).
- Design guidance: a concrete decision about choosing or composing this component. Omit it when there is nothing useful to decide. Compare related components when the same intent could plausibly lead to the wrong choice.
- Installation: the actual component item and its dependencies. Never invent a public host, package or release. Link common setup instead of repeating it.
- Basic usage: the smallest usable example, including imports and necessary labels/state. Show the result before advanced configuration.
- Structures: public anatomy and valid nesting; mark required/optional parts and caller-owned content. A leaf needs one sentence, not an invented compound API. Repository folders belong in architecture guidance.
- Examples: one reader decision per example, with a working preview and exact copyable code. See [variants and examples](#variants-and-demos). An API table can enumerate ordinary values without a separate preview for every permutation.
- API reference: exact public props, types, defaults, requiredness, callback payloads and ownership. Describe forwarded native props/ref/render support only where the owner supports them. Link inherited upstream contracts with the installed version boundary.

Keep product policy and business content with the caller. Demo CSS may arrange the task; it cannot repair component padding, states or focus. Use [API and structure](#api-and-structure) and [CSS ownership](#styling-ownership).

Verify source claims, compile changed MDX and executable snippets, resolve links/anchors, and confirm the registry item exists. A correct heading sequence does not establish accurate content. Rendered/interaction changes use the scoped independent acceptance required by AGENTS.md. Text-only changes need text/reference review. Record unknown visual results honestly.

After changing a demo or Preview composition, run `npm run docs:examples -- --write`; `npm run docs:check` rejects stale recipes, downloads and bindings. Keep generated JSON/archive files as projections of canonical demos. Recipes use JSX with complete helper/data/style dependencies; preserve their exact displayed props and list additional install requirements. Do not relabel emitted JSX as TypeScript.


<a id="api-and-structure"></a>

# API and code structure

Use when changing public properties, parts, state or source ownership. Canonical source is the API authority; docs and examples must agree with it.

## Compose canonical owners

**Do:** search the manifest and `src/components/ui/` first. Keep component TSX and owned CSS there; shared semantic values live in the existing token authority. Share a private recipe when semantics prevent direct composition and document that constraint.

**Good:** a compound panel uses the real Button, Loader, Collapsible and Progress for their jobs.

**Avoid:** a div with `ui-button` classes and parallel click/keyboard logic, or an imported Button that is never used while a copied button remains.

**Proof:** inspect actual rendered/source ownership. Demos own business content/state; they do not repair component padding or behavior. Build only package/registry/web projections needed for changed public contracts.

## Make properties express independent decisions

- Prefer native names and semantics: `disabled`, `readOnly`, `name`, native attributes and refs.
- Preserve an owner's established prop vocabulary; do not rename `variant` to `appearance` for cosmetic consistency alone.
- Use finite enums for mutually exclusive choices. Separate independent axes such as hierarchy and size. Do not add several booleans that can contradict each other.
- State exact defaults and permitted values. A useful design idea is a proposal until the actual API supports it.
- Name callbacks for the observable change they request. Document payload, controlled state and side effects. Use installed types/inference that prevent real mistakes.
- Provide useful parts/render composition for caller layout. Convenience compositions use those same parts.

**Good:** Button uses its existing `variant` and `size` values. Accordion exposes its supported `multiple` setting and controlled/uncontrolled value semantics.

**Avoid:** `isBig`, `compact`, and `extraLarge` flags on one control, or `onApprove` silently executing a caller's tool.

**Proof:** type/source review of exact values/defaults and one meaningful consumer. Changes in behavior/API receive targeted checks, not a blanket release cycle.

## Keep data and side effects explicit

The host owns business policy, transport, persistence and tool execution. Local interaction state can be convenient; controlled behavior must remain possible when the user job needs it. Preserve identity, ordering, user disclosure, cancellation and unknown states.

For AI, read [AI library design](ai-library-design.md): SDK-free contracts/views, optional version-specific TanStack AI/Vercel AI SDK adapters, no forced engine provider. React UI remains React. Approval, execution and successful output are separate facts.

**Good:** the caller receives a change request, updates its store and passes the new value; adapters normalize actual provider capabilities.

**Avoid:** infer final success from stream end or invent a percentage without a known total.

**Proof:** trace the changed data/callback path and its observable result. Claim reference parity or an advantage only after comparing current primary sources and demonstrating the selected benefit.

## Evolve without parallel APIs

Before a breaking change, list affected source, exports, registry, package, demos and docs. Choose a deliberate migration. Stable APIs and escape routes matter more than matching every reference's names. Do not invent a general state engine, plugin system or new abstraction without a real in-scope consumer.

## Choose the smallest contract that fits

Start with a native element plus typed attributes for a leaf. Use compound parts when callers need meaningful structural control or shared interaction context. A convenience composition can wrap those parts for the common path; it must not become a second implementation. Keep private helpers private until a real external composition needs them.

| Decision | Prefer | Avoid |
| --- | --- | --- |
| Exclusive choice | Existing finite enum (`variant`, `placement`) | Several booleans that can contradict each other |
| Independent choices | Separate axes (`variant`, `size`) | `largeDestructiveWithIcon` |
| Local editable state | Established `value`/`defaultValue`/change handler conventions | A setter that mutates caller data or switches controlledness silently |
| Content | Children/named slots for meaningful regions | Product-specific strings in the component |
| Identity | Caller IDs and stable keys | Array index as durable identity, regenerating IDs on reorder |
| Events | Observable change request with typed payload | Transport/persistence secretly triggered by a view |
| Styling | Owned CSS, semantic tokens and a deliberate escape route | One new prop for every CSS declaration |
| Invalid states | Discriminated types when they prevent actual misuse | `any`, casts or generic machinery that hide an impossible state |

Controlled means the app supplies the current value and responds to the change request. Uncontrolled means the component initializes and retains its own interaction state. Document defaults and transitions; do not imply a component's checked state proves server persistence. Cancellation, error, unknown completion and unavailable capability remain distinct.

## File and dependency shape

Keep a public owner in `<name>.tsx`, with `<name>.css` for its owned styles. Add `<name>.types.ts` or pure utilities only when they clarify a real reusable contract; a tiny owner does not need a directory of boilerplate. Keep internal implementation details under the established internal boundary. Existing file layout is a migration constraint, not a reason to duplicate an owner.

Export only intended public parts/types through the actual package barrel/subpaths. Registry metadata names the same source and transitive dependencies; documentation imports the supported path. Avoid importing the global barrel from a component when it creates cycles or pulls unrelated owners into the graph. Use direct canonical imports between components.

Separate React views from pure reusable data utilities where useful. Optional SDK adapters depend on the core, never the reverse. Do not make a runtime-neutral core into a claimed framework-neutral React library. Keep browser-only work in effects/events and check SSR implications for new platform access.

Review a new contract with one realistic common consumer and one meaningful customization. Test the actual risk: controlled change, invalid input, cancellation, focus/ref forwarding or install closure. Do not create broad test matrices for a naming or prose correction. Breaking changes need a concrete migration and affected consumers; no parallel alias family kept indefinitely for cosmetic parity.


<a id="styling-ownership"></a>

# Theme, component and example CSS

Use the owner that has the reason to change. A package boundary does not require a new visual system.

| Layer | Owns | Must not own |
| --- | --- | --- |
| Theme | Semantic colors, type, spacing, control/radius scales, shared motion and focus roles; light/dark mapping | A particular demo's layout or a single component's fix |
| Component | Structural layout, geometry, state selectors, variants, focus, functional animation/reduced motion; component-specific custom properties that callers actually need | App colors, product policy, resets for unrelated elements |
| Private shared recipe | One implementation detail used by owners for the same reason (e.g. grip geometry) | A new public “variant” with no user decision |
| Demo/example | Task arrangement, realistic content, fixture state, width constraints and content styling | Repairs to Button padding, focus, menu selection or any canonical appearance |
| Block/template | Product layout, data/persistence, workflow and business policy; composes canonical owners | Copies of component interaction logic |
| Docs shell | Page layout, prose, source display and documentation controls | Styling required by installed product components |

## Current source and delivery

`design-system/tokens.css` owns authored shared values. `src/components/ui/tokens.css` imports these for repository use; registry/package builders produce portable token output. Do not copy the repository import path into a consumer unchanged.

Keep new owner TSX/CSS together under `src/components/ui/`. Several historical adapters still use `foundation.css`; that is existing shared component styling, not the theme. Do not split it during a docs correction. Before any shared CSS edit follow the verified-baseline and preservation rules in AGENTS.md. New component-specific styling normally lives in `<owner>.css`; deliberate shared recipes remain shared.

Registry items must carry component TSX, owned CSS and transitive dependencies. Package builds must include CSS exports and declare side effects so bundlers do not discard styles. Do not claim each component is an independent npm package: inspect `packages/ghost-ui/package.json`. Current distribution uses `@ghost-ui/core` with subpaths plus source registry items. Publication/version availability is a separate fact.

Copied React component entries load their structural CSS and the shared foundation through static imports. The registry ships the complete transitive dependency closure, including generated theme defaults. Apply host token overrides after those defaults. `npm run styles:check` verifies every manifest owner's stylesheet reachability; preserve pure data/adapter entries without CSS imports. Package JavaScript stays CSS-free for server rendering: consumers explicitly load `styles.css` then `components.css`, or `full.css`. A clean consumer must not import the docs shell to look correct.

## Compose the actual styled owner

An import alone does not prove reuse. Compose the owner's public parts and keep its intrinsic appearance: typography, control sizing, padding, corners, paint, icons, arrows and interaction states. Use its supported size, variant and composition APIs before adding CSS.

- Calendar events, date cells and time-grid geometry belong to Calendar. Its command Buttons, Select triggers and overlays retain their own styling.
- Use `Popover.Arrow` for the shared smooth tip. Do not copy its SVG/path, build a rotated-square tip, or repaint it through a consumer selector.
- Use the real Header/Core/Footer parts. A consumer may arrange children or constrain a surface's width/height through public props; it must not clone those parts with different title scales and padding.
- Put constrained or scrolling content in Core, with essential actions in Footer and the arrow outside the scroller. A surface's available-height cap alone does not contain overflowing children; verify the short viewport.
- Keep borrowed-control layout on caller-owned wrappers/classes. Do not target another owner's private classes to change appearance, including with equivalent theme tokens or `!important`.
- If a recurring embedding context needs an option, add it once to the canonical owner and adopt it. `DatePicker embedded` lets an enclosing surface own its border/padding; Calendar and Date input use that contract.

Theme tokens define shared values; they do not authorize each consumer to reconstruct a component. A correction to a shared arrow, control or surface should propagate from one master. Verify the consuming composition and preserve unrelated consumers when extending that master.

## Customization without forks

Use a shared semantic token when the intent repeats across owners. Use a component custom property for a real local customization (and document its default/fallback). Use a className/style or composition escape route for a one-off host arrangement. Add a variant only when it names a recurring supported decision with coherent behavior and states.

Avoid global `button { ... }`, `!important` fixes, palette steps in ordinary controls, and selectors reaching into another owner's private structure. Namespace owned classes with `ui-`; use `web-` or an isolated example class for docs. An allowed host customization is distinct from a demo patch needed to make the default work.

## Show the code that produces the preview

Preview source includes its content, state and necessary example CSS. Shared component CSS is installation material, not disguised example CSS. If a snippet uses an alias, helper, image or fixture data, include it or state how the reader obtains it. Do not present an import of a private demo module as standalone product code. Never show a native button in source while rendering the Ghost Button in the preview.

Proof follows the change: accurate manifest/import review for prose, clean installed consumer for changed delivery, scoped live rendering for changed styles. Equal output hashes prove synchronization, not preservation of unrelated rules.


<a id="variants-and-demos"></a>

# Variants and examples

A public option earns its place by changing a reusable decision. An example earns its place by teaching a useful decision. Neither is justified by a different title, icon or business scenario alone.

| Kind | Meaning | Example | Documentation treatment |
| --- | --- | --- | --- |
| Variant/axis | Mutually exclusive supported choice | Button variant: subtle/solid/ghost | Explain the purpose of each value; compare values together where useful |
| Independent configuration | Separate caller decision | Button size, Accordion multiple | Give the decision its own example; avoid mixing size with emphasis |
| State | Condition during use | Focused, pending, invalid, disabled | Show when it changes behavior or caller handling; do not add a prop merely for a specimen |
| Composition | Existing parts arranged for another valid need | Field with label, help and Input | Explain ownership/nesting; use the same canonical owners |
| Domain use case | Same contract, different content | Project vs product selector | Add only if it teaches a new constraint, not another skin |
| Block | Several owners plus workflow/policy | Account preferences with save/retry | Separate copyable product composition, not an overloaded component flag |
| Template | Pages/flows plus application structure | Ecommerce settings area | Separate from a component detail page |

## Admission test

For a proposed example, answer:

1. What decision or failure would the reader understand after using it?
2. Does the actual current API support it, and who owns its data/side effects?
3. Is another example already teaching the same thing?
4. Can a smaller composition show it without unrelated product machinery?

If there is no new decision, combine or omit it. If business policy dominates, make a block/recipe. Add a component prop only when the recurring behavior belongs to that owner. Preserve useful lower-level parts rather than forcing all use cases into a convenience wrapper.

## Coverage without a Cartesian product

Inventory supported axes, their values/defaults, meaningful states and compositions. The API reference enumerates the complete public contract. Examples demonstrate the choices that change adoption or composition. Group ordinary values into one comparison (e.g. sizes); show separate examples for distinct behavior (e.g. single/multiple selection). Do not require every color × size × icon × direction × state permutation.

Cover an interaction between axes when it can fail for a concrete reason: long labels in a compact control, multiple selection with disabled options, a portal inside a modal, range bounds across daylight saving. Do not add narrow/theme/keyboard matrices to a prose correction; choose verification from actual change risk.

Title examples after the behavior or choice: “Grouped options”, “With a description”, “Controlled selection”, “Empty results”. State the reason in one sentence if the preview cannot make it clear. A preview and its source must use the same value. Do not rename established props just to make vocabulary uniform.

For believable task content, thumbnail composition, source completeness and live proof use [Preview craft](preview-craft.md). For page placement use [Component documentation](../../component-documentation/SKILL.md). For new public names use [Naming and taxonomy](naming-and-taxonomy.md).


<a id="preview-craft"></a>

# Main previews, thumbnails and example snippets

The component is the subject. Show enough context for a reader to recognize its job and try its defining behavior. Do not build a small fake application around every control.

| Surface | Purpose | Composition | Direct check |
| --- | --- | --- | --- |
| Main preview | Recognize and try the component | One useful task; actual canonical owner; relevant result/state | Inspect whole preview at normal size, then perform its primary interaction |
| Thumbnail | Recognize the catalogue entry | Same visual identity; fewer details; readable at destination size | Inspect real gallery tile/crop; use static truthful state if interaction would distract |
| Configuration example | Understand one caller decision | Same basic task, one changed axis; short purpose sentence | Compare changed result and copyable source |
| State example | Understand a consequential condition | Real pending/empty/error/disabled/overflow semantics | Trigger result or mark fixture as illustrative; include recovery where meaningful |
| Block/template | Complete a product job | Multiple owners plus product policy and transitions | Verify the end-to-end task, separately from component acceptance |

## Compose the smallest believable task

A Switch can say “Mute notifications”; it does not need settings navigation. A menu needs meaningful commands and the actual opening trigger. A table needs enough columns/rows to demonstrate the documented behavior, not a second toolbar that duplicates the header controls. An AI task fits Activity, Composer or ToolApproval; a simple Separator does not automatically need a conversation.

Put content directly into the component. Keep external captions only for information the component cannot communicate, such as a fixture's scope or asynchronous failure. Keep accessible names even when visible prose is removed. Use text with Toggle examples, arrows with Tooltip/Popover designs, and the true owner for loading or progress.

The first view should be useful at rest. Do not rely on autoplay to explain the component. Avoid random data, current-time drift, fabricated success, infinite “loading” with no deliberate state example, fake links and inert buttons that appear to perform a meaningful action. If the demo cannot complete a server action, make its local behavior truthful and describe the boundary in documentation.

## Make every copyable snippet honest

Use exact current imports, parts and supported props. Include state/data/helper functions needed for the example. Remove docs wrappers and private aliases, but preserve required labels, event handling and styles. A short excerpt may be labelled an excerpt; do not call it a working standalone example. Source tabs should correspond to the rendered configuration, including optional values that change the appearance.

Use the existing Preview/SnippetPreview owners. Preview layout constrains the stage, not the component's internal geometry. Avoid hardcoded preview-only repairs. Where exact raw source contains multiple exported examples, prefer selecting the relevant self-contained example rather than making readers untangle a file of unrelated states.

In this repository, `npm run docs:examples -- --write` projects the exact displayed composition into copyable JSX and per-page downloads. It bundles demo helpers, styles and sample assets while keeping installed component owners external. `npm run docs:check` checks all rendered wrappers and rejects stale output. Keep specialized example selection, such as Chart metadata filtering, in one shared owner. An opt-out from prose styling must explicitly restore the intended example font.

## Thumbnail judgment

Use real destination dimensions and crop behavior. Keep the distinctive structure visible, sufficient insets around labels and controls, and coherent density. Don't shrink a whole page to make it fit. Do not erase required meaning to achieve a cleaner tile. Main preview and thumbnail may differ in detail without becoming different components.

Paper order: Preview first, Thumbnail second, then meaningful configurations/states, then styling proposals. Use one frame for each exact state. Existing approved frames can be reused; new frames are needed only when a design decision needs drawing. Do not create artboards for prose-only corrections.

## Acceptance

Look at the whole current preview before measuring. The subject must read clearly, controls must have internal space and the relevant hover/selected/focus states must remain distinct. A source-only review marks visual result unknown. Inspect current original images from the dedicated reviewer; measurements and passing builds support judgment rather than replacing it. Keep the check bounded to the changed outcome.


<a id="sections"></a>

# Decide what each section should do

## Library guides

Library pages teach adoption, composition and extension. Use a library's actual reader tasks to choose its pages; the component section order below does not apply. Start with the choice of entry point and a minimal working public-import integration, then explain data/state ownership, customization, reference and troubleshooting. Link component pages for anatomy, appearance and styling.

Name what Ghost adds, what the upstream engine owns and what the caller owns. State installed version boundaries and optional dependencies. Explain controlled values through the callback/update cycle, serialization and asynchronous failure where relevant. Give a lower-level escape route; do not rename an upstream API merely to create a Ghost abstraction. Link exhaustive upstream reference instead of copying it.

Compile every executable example in the changed library families, including optional integrations, and check an installed public entry when exports change. Treat SDK capability flags precisely: native support, caller-supplied data and outbound commands are different boundaries. Review the actual prose as a newcomer and as an experienced engineer; compilation supports editorial judgment.

## Per-page review checklist

Review every item against the current implementation. Record specific evidence, not a bare “pass”.

| Criterion | Required decision |
| --- | --- |
| Summary | One action-led sentence explaining the user's job; canonical display name |
| Guidance | A useful selection/composition decision, or a reason the section adds no value |
| Anatomy | Valid public nesting and required/optional parts; a leaf stays a leaf |
| Configurations | Inventory meaningful independent axes/states; map each to an example or an explicit reason to group/omit it; no unsupported variants or template-sized examples |
| API | Actual props/defaults/callback payloads, dependencies and caller state ownership |
| Writing | Consistent terms, capable-reader language, concrete headings and no unsupported praise |

Mechanical lint and code compilation cannot judge these decisions. A source-backed editorial review must accompany them and become stale when its document or reviewed owner changes. Keep that evidence separate from live visual/runtime acceptance. Library docs instead teach installation, data contracts, state/operations, integration and API behavior; link component pages for visual styling.

Research in this order: the user task → current public source/types and defaults → real consumers and previews → closest Ghost alternatives → current upstream behavior docs. Keep a small source map while drafting; it need not appear on the public page. Prefer a direct implementation fact over a remembered API. If a feature is missing, describe the limitation or fix the owner; don't document the desired future as current behavior.

| Section | Reader question | Include | Leave elsewhere |
| --- | --- | --- | --- |
| Preview | Is this the thing I need? | One working, believable task at normal size | Installation, caption repeating the action, full app shell |
| Design guidance | Why choose this, and how should I compose it? | Relevant alternatives, content hierarchy, consequential accessibility/interaction choices | Generic praise, full prop catalogue, implementation history |
| Installation | How do I obtain working source/styles? | RegistryInstall with the real item; common setup link; unusual dependency if material | Localhost-only commands, unverified npm release claims, whole kit by default |
| Basic usage | What is the smallest usable composition? | Import, required parts, label, minimal state/data; a result the reader can recognize | Every optional prop, ellipses hiding required logic, extra app infrastructure |
| Structures | Which parts fit where? | Actual parent/child nesting, required/optional roles, owned content, portal location where it matters | Repo file tree, flat list implying all parts are siblings, invented Root |
| Examples | How does this choice change the result? | Purpose, changed axis/state, live result, matching complete source | Color × size × state Cartesian products, business templates masquerading as variants |
| API reference | What exactly does the contract accept/do? | Props/types/defaults, callbacks and state semantics, parts and native/ref support | Selection guidance, duplicated upstream reference, guessed defaults |

## Design guidance is a decision aid

Write it when a likely caller can make a meaningful mistake. Start with “Use [owner] when [task/constraint].” Add the nearest alternative and the discriminating condition, not a survey of the catalogue. Add content or composition guidance only if it changes a decision.

For example:

> Use Checkbox for independent choices that can be submitted together. Use RadioGroup when exactly one option must be chosen. Use Switch for a setting that takes effect immediately; make pending or failed persistence visible in the host.

This differs from “Checkbox is flexible and accessible”: the reader can act on the first. Link the alternatives. Do not imply that the view saves a setting or enforces application validation.

Useful comparison clusters: Button/Link; Checkbox/RadioGroup/Switch/Toggle; Select/Combobox/Autocomplete; Dialog/AlertDialog/Popover/Tooltip; Accordion/Collapsible; Table/DataGrid; Meter/Progress/Loader; DateInput/DatePicker/Calendar/Booking. Verify the actual Ghost owners before naming them.

Accessibility belongs here when callers choose the semantics: visible labels, accessible dialog title, equivalent non-drag input, error association, persistent status, keyboard interaction that changes composition. “WCAG compliant” is not a substitute for these instructions or tested evidence.

## Structures describe anatomy

Use `Structure items={...}` with real exported labels. Nest children according to the required context, not visual coincidence. Follow with one or two sentences that identify required parts, optional parts and caller content. A portal can render elsewhere in the DOM while belonging to the same React owner; explain that distinction where relevant.

Leaf example: “Button is a single control. Its children are the visible label; leadingIcon and trailingIcon are optional.” Compound example: “Dialog.Root owns open state. Trigger opens it; Popup contains Title and content. Description and Close are optional for the chosen composition; preserve an accessible name.” Check those exact part names against current source before copying this example.

Do not introduce fake grouping nodes such as `Checkbox` → siblings when the actual preview needs `Checkbox.Row` wrapping a control and label. API reference lists all exported parts; Structures explains the useful composition.

## Examples and API

Title examples after the demonstrated decision: “Multiple selection”, “With a description”, “Controlled value”. The task's content can be realistic without making “Enterprise ecommerce checkout” a variant. One sentence is enough if the preview tells the rest.

A prop description answers what changes, who owns it and what happens at a boundary. For callbacks include the payload meaning, not merely “callback function”. For controlled state name the paired change handler. Distinguish omitted defaults from computed defaults, unsupported combinations from optional choices, and component state from server completion.


<a id="writing"></a>

# Clear technical writing

Write only what helps the reader choose, build or troubleshoot. Remove a sentence if it repeats the preview, another section or common setup without adding a necessary decision. More words, pages and examples do not establish quality. Write for a capable reader who may be new to this topic. Lead with their task; use short connected paragraphs. Put the common path first and disclose advanced choices under named examples or reference. Keep precise technical names in code formatting and explain the concept in plain language nearby.

| Prefer | Avoid | Why |
| --- | --- | --- |
| “Choose more than one option with multiple.” | “Leverage multi-select functionality.” | Names the result and its control |
| “Pass value and update it in onValueChange to keep selection in your app.” | “Use controlled mode.” with no explanation | Explains the term through an action |
| “Use Link to navigate to another page.” | “Simply use the Link component, obviously.” | Direct without judging difficulty |
| “The caller saves the setting. Keep the previous value if saving fails.” | “The switch securely persists your setting.” | Truthful ownership and failure behavior |
| “Enter a label users can recognize.” | “Provide an appropriate accessible textual identifier.” | Familiar language preserves meaning |

Use sentence case, active voice and concrete verbs. Avoid “simply”, “just”, “obviously”, “powerful”, “seamless”, “production-ready” and “accessible” as unsupported praise. Do not repeatedly address beginners as beginners. A small example often teaches a term better than a long definition.

Keep introductions to one useful sentence. Use a comparison table only for genuine alternatives; two short alternatives often read better as prose. Use lists for parallel choices or sequential steps. Don't turn every sentence into a callout or bold label. Code/source paths and exact enum values remain exact, including capitalization.

The component summary starts with a concrete action and explains the job: “Select an independent option or confirm a choice.” Avoid noun definitions such as “An easily stylable checkbox” or “An input combined with a list”. Keep it one concise sentence, without styling praise or implementation history. Display names use the inventory's sentence-case label with spaces (“Checkbox group”, “OTP field”); code uses the actual identifier (`CheckboxGroup`, `OTPField`). Use that same display label in headings, breadcrumbs, gallery, sidebar, search and adjacent-page links.

Engagement comes from progress: recognize the result → try it → copy it → vary one decision → inspect the contract. Do not add jokes, mascot copy, tutorials on unrelated JavaScript, or decorative app scaffolding to make a page “delightful”.

Edit in two passes. First verify truth against source, including examples and dependencies. Then remove repetition and jargon. Read each section alone: can its intended reader answer the section's question? Keep an explicit limitation when removing it would create a false promise.

Primary references: [Google Technical Writing: words](https://developers.google.com/tech-writing/one/words) for stable terms and definitions; [Diátaxis](https://diataxis.fr/) for distinguishing practical guidance, explanation and reference. Ghost's page order and visual voice are project choices.

