On this page

Lists a long page's sections beside the text, so readers can see its shape and jump to a part.

Organism · stable · v1.0.0 · owner: Site system lead · contract 19 of 20 points (open: figma)

Do and don't

Do: A long page

Rendered by contents.ts

Open example: On this page · Do: A long page Use the full-page example to follow page links.

Three sections, a map.

Do: Japanese

Rendered by contents.ts

Open example: On this page · Do: Japanese Use the full-page example to follow page links.

Translated title.

Don't: Two sections

Rendered by contents.ts

Renders nothing for these props (by design).

Renders nothing.

Don't: h3 entries

Rendered by contents.ts

Renders nothing for these props (by design).

Only h2 sections are listed.

Rules

RuleWhyCheck
Rendered only for three or more h2 sections.A map earns its place only on a long page.Automated: tests/unit/site-system.test.ts

API

PropTypeRequiredDefaultWhat it does
headingslistYesThe page's headings (level, id, text).
langen | jaNo"en"Title language.

Contract details

The full contract: identity, anatomy, variants, states, tokens, layout, motion, accessibility, content, tests

Identity

AspectValue
Idcontents
LayerOrganisms
Categorynavigation
OwnerSite system lead
Statusstable
Version1.0.0
Sourceapps/showcase/site/system/organisms/contents.ts (private repository; the contract and the render function are this one module)
VersionDateChange
1.0.02026-10-26On this page as one module: its markup moved out of the page builder (scripts/site) into the system.

Use when

  • Pages with three or more h2 sections. Why: Long pages need a map; short ones do not.

Do not use when

  • Pages with fewer than three sections. Why: A two-item list is noise; it renders nothing.

Anatomy

PartWhat it is
rootnav.toc named by its h2
titleh2#toc-title
listol of in-page links

Made of: heading, text-link.

Used in: prose-section.

Variants

VariantWhenWhy
defaultWherever the page declaration places it.One shape per job keeps pages predictable.

States

StateRendered or not applicable
defaultdefault
hoverLinks underline.
focus-visibleThe --focus ring.
activeNot applicable: Links.
disabledNot applicable: Every entry links to a heading on the page.
loadingNot applicable: Build time.
emptyFewer than three sections: nothing is rendered.
errorNot applicable: No data that can fail.
currentNot applicable: No scroll spy: the list does not change as you scroll.
visitedNot applicable: In-page links.
expandedNot applicable: Does not open.

Tokens

PartToken
title.font--type-eyebrow
link.color--ink-2
--contents-top-header-hvar(--header-h)
--contents-top-space-9var(--space-9)
--contents-font-type-labelvar(--type-label)
--contents-margin-bottom-space-6var(--space-6)
--contents-border-left-linevar(--line)
--contents-padding-space-3var(--space-3)
--contents-padding-space-6var(--space-6)
--contents-margin-left-space-2var(--space-2)
--contents-font-size-fs-smallvar(--fs-small)
--contents-color-ink-2var(--ink-2)
--contents-color-inkvar(--ink)
--contents-border-left-color-indigovar(--indigo)
--contents-font-type-strongvar(--type-strong)
--contents-border-left-color-threadvar(--thread)

Layout

AspectValue
breakpointsChecked at 390, 768, 1024 and 1440 px; a sticky side column from 1024 px, above the text below it.
wrappingText wraps; nothing scrolls sideways.
textExpansionJapanese runs 20 to 40% longer; headings break between phrases (jaBreaks) and blocks grow downwards.

Spacing and rhythm

AspectValue
internal--space-3 between entries.
externalIn the page grid's side column.
rhythmBeside the prose.

Motion

AspectValue
NoneNo intrinsic element animation. The optional claude-entrance consumer profile may translate below-fold structure once (20px, --dur-weave, --ease-enter, --stagger); reduced motion disables it. This preserved baseline entrance is separate from element playback.

Runtime and reuse

  1. Render-only element; mount any registered child enhancements separately. Preserve required Site CSS, fonts, responsive and locale rules from nativeElement.

Accessibility passport

AspectValue
rolea landmark or list, as stated in its parts
nameIts visible text
keyboardLinks and buttons inside, in reading order.
focusThe --focus ring on every link and button inside.
screenReaderRead in source order; decorative weaving is aria-hidden.
contrastInk on cotton 14:1; text on every dye field 4.5:1 or better (checked by check-brand).
targetLinks and buttons are 44 px tall.

Content

SlotLengthVoice
entryThe heading's textAs written

Good: “On this page”

Bad: “TOC”

Japanese: このページの内容

Icons and illustrations

None: this element uses no icon or illustration of its own.

Decisions and exceptions

  • None.

Usage

49 uses across the built pages (measured by npm run site:system).

Tests

AspectValue
unittests/unit/site-system.test.ts: renders every do and don't example through the registry and checks the classes it owns
visualNot yet: there are no screenshot baselines; the Library page is checked for sideways scroll at 1440 px by tests/site/system.spec.ts
a11ytests/site/system.spec.ts: axe (0 serious or critical) on the element's Library page in light and dark
parityscripts/site/system/check.ts: Library examples are rendered by the same render function the site imports

Figma

not-yet: The Loom Site Figma library is the last stage of the plan; this element is not mapped yet.

Open in Storybook

Start with a conversation about your system.

We read your system, show you what we found, and agree with your team what to fix first.