# Reading

Article and project layouts, outlines, media and installation instructions.

- Group: Website
- Import: `import { DetailMasthead } from '@misoto22/folio/website'`
- Page: https://ui.misoto22.com/components/reading/

## When to reach for it

Build long-form reading surfaces with consistent section spacing and accessible navigation.

## Best practices

### Do

- Supply localized labels, descriptive links and meaningful image alternatives.

### Don’t

- Do not put service credentials, routing logic or backend models inside presentation components.

## DetailMasthead

### Props

- `backLink` — `ReactNode`.
- `title` (required) — `string`.
- `dek` — `ReactNode`.
- `context` — `ReactNode`.
- `aside` — `ReactNode`.
- `actions` — `ReactNode`.
- `metadata` — `ReadingMetadataItem[]` default `[]`.
- `width` — `'page' | 'fill'` default `'page'`.

## ReadingLayout

### Props

- `outline` — `ReactNode`.

Also accepts: `HTMLAttributes<HTMLDivElement>`.

## ReadingSection

`seamless` lets a structured child continue directly from the section rule without drawing a second seam.

### Props

- `title` — `ReactNode`.
- `caption` — `ReactNode`.
- `lead` — `ReactNode`.
- `compact` — `boolean`.
- `seamless` — `boolean`.

Also accepts: `Omit<HTMLAttributes<HTMLElement>, 'title'>`.

## ReadingLead

### Props

- `children` (required) — `ReactNode`.
- `muted` — `ReactNode`.
- `description` — `ReactNode`.

## RecordPager

### Props

- `label` (required) — `string`.
- `previous` — `ReadingPagerItem`.
- `next` — `ReadingPagerItem`.

## isSelfNumbered

## numberToc

## TableOfContents

### Props

- `items` (required) — `OutlineItem[]`.
- `label` (required) — `string`.
- `numbering` — `'auto' | 'none'` default `'auto'`.
- `onNavigate` — `(id: string) => void`.
- `expanded` — `boolean` default `false`.

## MobileOutline

### Props

- `items` (required) — `OutlineItem[]`.
- `title` (required) — `string`.
- `openLabel` (required) — `string`.
- `closeLabel` (required) — `string`.

## ReadingProgress

## AuthorPanel

### Props

- `avatar` — `ReactNode`.
- `name` (required) — `string`.
- `role` — `ReactNode`.
- `bio` — `ReactNode`.
- `links` — `ReactNode`.

## ReadingFigure

A reading image can preserve its source framing with `fit="contain"`, rather than silently cropping it to a house ratio.

### Props

- `media` (required) — `ReactNode`.
- `captionStart` — `ReactNode`.
- `captionEnd` — `ReactNode`.
- `width` — `'page' | 'fill'` default `'page'`.
- `ratio` — `string` default `'16 / 8'`.
- `fit` — `'cover' | 'contain'` default `'cover'`.

## MediaPlayback

### Props

- `src` (required) — `string`.
- `poster` — `string`.
- `label` (required) — `string`.
- `playLabel` (required) — `string`.
- `pauseLabel` (required) — `string`.
- `fallback` (required) — `ReactNode`.

## ActionBand

A terminal project invitation with one strong entry action and quieter supporting actions.

### Props

- `title` (required) — `ReactNode`.
- `description` — `ReactNode`.
- `actions` — `ReactNode`.
- `eyebrow` — `ReactNode`.

## FeaturePairs

### Props

- `items` (required) — `{ id?: string; label?: ReactNode; title?: ReactNode; description: ReactNode }[]`.

## DevicePreview

### Props

- `kind` (required) — `'browser' | 'phone'`.
- `label` — `string`.
- `media` (required) — `ReactNode`.
- `caption` — `ReactNode`.

## PreviewPair

### Props

- `desktop` (required) — `ReactNode`.
- `mobile` — `ReactNode`.

## CommandTabs

### Props

- `label` (required) — `string`.
- `tabs` (required) — `CommandTab[]`.
- `copyLabel` (required) — `string`.
- `copiedLabel` (required) — `string`.
- `footer` — `ReactNode`.

## ReadingSurface

### Props

- `numbered` — `boolean`.

Also accepts: `HTMLAttributes<HTMLDivElement>`.

## ReadingForm

### Props

- `inline` — `boolean`.

Also accepts: `React.FormHTMLAttributes<HTMLFormElement>`.

## ArchitectureColumns

### Props

- `columns` (required) — `{ title: string; connected?: boolean; nodes: ArchitectureColumnNode[] }[]`.
- `foundation` — `ArchitectureColumnNode[]`.

## TokenLine

### Props

- `items` (required) — `{ label: ReactNode; strong?: boolean; icon?: ReactNode }[]`.
- `label` — `ReactNode`.
- `separator` — `string` default `'·'`.

## ContentFigure

### Props

- `children` (required) — `ReactNode`.
- `caption` — `ReactNode`.
- `wide` — `boolean`.

## ReadingPage

### Props

- `children` (required) — `ReactNode`.

Also accepts: `HTMLAttributes<HTMLElement>`.

## CommandSnippet

### Props

- `code` (required) — `string`.
- `pieces` — `CommandPiece[]`.
- `copyLabel` (required) — `string`.
- `copiedLabel` (required) — `string`.
- `className` — `string`.

## Example — article and outline

```tsx
import { Text } from '@misoto22/folio'
import { DetailMasthead, ReadingLayout, ReadingSection, RecordPager, TableOfContents } from '@misoto22/folio/website'

<div className="w-full">
  <DetailMasthead title="A practice of attention" dek="A few observations from the daily walk."
    width="fill" metadata={[{ label: 'Published', value: '7 September 2026', dateTime: '2026-09-07' }]} />
  <ReadingLayout outline={<TableOfContents label="Example article sections" items={[
    { id: 'reading-notice', label: 'Notice', level: 2 },
    { id: 'reading-return', label: 'Return', level: 2 },
  ]} />}>
    <ReadingSection id="reading-notice" title="Notice"><Text>A familiar route still changes with the light. Record one detail before naming the whole scene.</Text></ReadingSection>
    <ReadingSection id="reading-return" title="Return"><Text>Compare what you wrote on the next visit. The difference often matters more than the first impression.</Text></ReadingSection>
    <RecordPager label="Essay navigation" next={{ link: <a href="#next-essay" />, direction: 'Next', title: 'Keeping a field journal' }} />
  </ReadingLayout>
</div>
```
