Pilot

RN-universal Typography pilot

Scaffolded

RN does not have h1..h6 — semantic headings are expressed as <Text accessibilityRole='header'> + aria-level. This pilot establishes the canonical TpGroup typography primitives: Heading (levels 1-6), Body, Caption, Code, Eyebrow. All read type scale, weight and colour from shared tokens.

Scale

Section eyebrow

Heading level 1 — 36px semibold

Heading level 2 — 30px semibold

Heading level 3 — 24px semibold

Heading level 4 — 20px semibold

Heading level 5 — 18px semibold
Heading level 6 — 16px semibold
Body copy — 16px regular. Default paragraph style for long-form content, row cells, and descriptions. Line height is relaxed enough to scan quickly.
Caption — 12px muted. Used for metadata, labels, timestamps.
Inline code example: wrap identifiers in RnCode for clear affordance.

Semantic mapping

PrimitiveWeb DOM (via RN Web)Native renderingToken source
RnHeading level=1<h1><Text accessibilityRole="header"> announced as heading, rank 1font-size-4xl + font-weight-semibold
RnHeading level=2<h2>As above, rank 2font-size-3xl + font-weight-semibold
RnHeading level=6<h6>As above, rank 6font-size-base + font-weight-semibold
RnBody<div><Text>font-size-base + line-height-normal
RnCaption<div><Text>font-size-xs + color-text-tertiary
RnCode<div><Text>font-family-mono + bg-muted
RnEyebrow<div><Text>font-size-xs uppercase tracking-wider

Why RN cannot use h1..h6 directly

React Native's only text primitive is <Text>. Heading semantics are expressed through the accessibilityRole and aria-level props. RN Web translates these to semantic <h1>..<h6> elements on the DOM so screen readers, outline-mode in browser dev tools, and SEO crawlers behave identically to the shadcn version.