Skip to content

Foundation: Docs Hierarchy (Nested Outline)

FieldValue
TypeSkill Resource
Source~/.copilot/skills/design/references/docs-hierarchy.md
DescriptionNot specified

Source Content

Foundation: Docs Hierarchy (Nested Outline)

Source of truth: .storybook/storybook-docs.css — the [data-docs-mdx-article] outline geometry. The depth of each element is tagged at runtime by markDocsSectionBodies in src/lib/mdx/docs-mdx-components.tsx (it sets data-docs-subsection-depth on every heading and its following content). CSS turns that depth into a subtle, cumulative indent. Never indent docs prose by hand in an MDX page — fix it here so every page inherits it.

The rule

Every level nests one subtle 0.75rem step under its parent. Body text, lists, tables, and embedded components all inherit their section’s indent — nothing jumps back to the left margin under its heading. Markers (I., A., 1.) and heading text move together as one block.

ElementLeft offset from article edge
H2 heading0 (roman numeral hangs in the outer gutter)
H2 body / lists / tables / components0.75rem
H3 heading + its body / tables / components0.75rem
H4 heading + its body1.5rem
H5 / H62.25rem / 3rem
List bullet/number textsection indent + 1.25rem marker gutter

Formula: a heading at level L (H2 = 2) sits at (L − 2) × 0.75rem; its body aligns to that same left edge. There is no per-level marker offset — body aligns to the heading’s left edge so no single step ever exceeds 0.75rem.

Token values

Defined on the [data-docs-mdx-article] container:

--docs-outline-step: 0.75rem; /* the per-level nesting step — keep subtle */
--docs-outline-marker: 1rem; /* width of the A./1. marker column */
--docs-depth-h3-marker: var(--docs-outline-step); /* h3 heading = 1 step */
--docs-depth-h3-text: var(--docs-outline-step); /* h3 body = 1 step (aligns to heading) */
--docs-depth-h4: calc(var(--docs-outline-step) * 2); /* 1.5rem */
--docs-depth-h5: calc(var(--docs-outline-step) * 3); /* 2.25rem */
--docs-depth-h6: calc(var(--docs-outline-step) * 4); /* 3rem */

On mobile (≤640px) the step stays 0.75rem; only the marker columns shrink slightly.

Why subtle

The step is 0.75rem, never 1.25rem+. Deep pages (H2 → H3 → H4 → list) must not run out of horizontal width or feel like a staircase. The indent only needs to be noticeable, not large — readers should be able to tell parent from child at a glance, nothing more.

Don’ts

  • Don’t add margin-left / pl-* to headings or paragraphs inside an MDX page to “fix” indentation — it will fight this system. Fix the shared CSS instead.
  • Don’t let a table or an embedded component sit flush-left under a heading. They are section content and inherit the section indent (the > h2 ~ table[data-docs-section-body] rule restores it).
  • Don’t compound the step (heading-marker + marker + gap). That produced the old ~3.25rem H3 indent. Each level is exactly one step past its parent.
  • Section collapse is native <details>/<summary>, built automatically at compile time by the rehype-docs-sections plugin — pure HTML/CSS, zero JavaScript. Never hand-roll an Accordion, a manual <details>, or a JS click-to-collapse around docs sections; the shared pipeline already wraps every heading. Indentation comes from that <details> nesting, not from hiding content.

See also lists.md (list marker gutters) and spacing.md (the 8pt scale these steps relate to).