Typography

Updated: Sep 24, 2026
Choose one complete toolkit text appearance for each text element. The appearance owns font family, size, weight, line height, and the optical block padding that aligns small text with the rest of a row.
The only text face is Noto Sans, in a regular, a medium, and a bold weight. App sets it up at runtime: it prefers a copy already installed on the device and otherwise loads the required weights from the Google Fonts content delivery network. There is nothing to install and no font file to bundle.

The appearances

AppearanceTextStyle memberTextAppearance constantCSS class
Numeral 1
TextStyle.NUMERAL1
TextAppearance.NUMERAL1
uit-text-numeral1
Numeral 2
TextStyle.NUMERAL2
TextAppearance.NUMERAL2
uit-text-numeral2
Display 1
TextStyle.DISPLAY1
TextAppearance.DISPLAY1
uit-text-display1
Heading 1
TextStyle.HEADING1
TextAppearance.HEADING1
uit-text-heading1
Heading 2
TextStyle.HEADING2
TextAppearance.HEADING2
uit-text-heading2
Body 1
TextStyle.BODY1
TextAppearance.BODY1
uit-text-body1
Body 1 emphasized
TextStyle.BODY1_EMPHASIZED
TextAppearance.BODY1_EMPHASIZED
uit-text-body1-emphasized
Body 2
TextStyle.BODY2
TextAppearance.BODY2
uit-text-body2
Body 2 emphasized
TextStyle.BODY2_EMPHASIZED
TextAppearance.BODY2_EMPHASIZED
uit-text-body2-emphasized
Label
TextStyle.LABEL
TextAppearance.LABEL
uit-text-label
Label emphasized
TextStyle.LABEL_EMPHASIZED
TextAppearance.LABEL_EMPHASIZED
uit-text-label-emphasized
Meta 1
TextStyle.META1
TextAppearance.META1
uit-text-meta1
Meta 1 emphasized
TextStyle.META1_EMPHASIZED
TextAppearance.META1_EMPHASIZED
uit-text-meta1-emphasized
Meta 2
TextStyle.META2
TextAppearance.META2
uit-text-meta2
Meta 2 emphasized
TextStyle.META2_EMPHASIZED
TextAppearance.META2_EMPHASIZED
uit-text-meta2-emphasized
Meta 3
TextStyle.META3
TextAppearance.META3
uit-text-meta3
Numeral appearances are for glanceable figures such as a timer or a metric. Display and heading appearances are for genuinely dominant information. Most screen content is body, label, and meta.
Sizes descend across the table, so a lower row is never larger than the row above it. An emphasized appearance keeps the size and line height of its base appearance and only raises the weight; it is the supported way to emphasize a run of text, in place of a <strong> or a custom font-weight.
Label and Meta 1 share a size and line height, so choose between them by what the text is — a control or field label versus supporting metadata — rather than by how big it looks. Their emphasized variants are not interchangeable: LABEL_EMPHASIZED is bold where META1_EMPHASIZED is medium.

Choose an appearance API

There is one set of appearances and three ways to name it.
ExportWhat it isWhere it is used
TextStyle
The value union accepted by TextView’s textStyle prop.
<TextView textStyle={TextStyle.BODY2} />
TextAppearance
A constant map from appearance name to the CSS class that implements it.
className={TextAppearance.BODY2}
uit-text-*
The global CSS classes the stylesheet declares.
Plain CSS and non-React markup.
TextView resolves the TextStyle you pass to exactly the same class that the matching TextAppearance constant holds, so the two paths always render identically. Prefer TextStyle inside TextView and TextAppearance everywhere else; hand-writing the class string is a last resort because nothing keeps it in sync.
Two supporting types are exported alongside the constant:
TypeMeaning
TextAppearanceKey
The union of appearance names — 'BODY1' \| 'META2' \| …. Useful for a prop that selects an appearance by name.
TextAppearanceValue
The union of the class-name strings the map holds. Useful for a value that must be a real appearance class.
import {
  TextAppearance,
  type TextAppearanceKey,
  type TextAppearanceValue,
} from '@wearables-ui-toolkit/mrbd';

interface CaptionProps {
  appearance: TextAppearanceKey;
  children: string;
}

function Caption({ appearance, children }: CaptionProps) {
  const className: TextAppearanceValue = TextAppearance[appearance];
  return <figcaption className={className}>{children}</figcaption>;
}

Rendering text

Prefer TextView, which pairs an appearance with a semantic color role and lets you choose the HTML element:
import { TextColor, TextStyle, TextView } from '@wearables-ui-toolkit/mrbd';

<TextView as="h1" textStyle={TextStyle.HEADING1}>
  Today
</TextView>
<TextView textStyle={TextStyle.BODY1}>Current conditions</TextView>
<TextView textStyle={TextStyle.META2} textColor={TextColor.SECONDARY}>
  UPDATED NOW
</TextView>
TextView defaults to TextStyle.BODY1, TextColor.PRIMARY, and a span element. as accepts span, p, div, h1 through h6, and label. Choose the element from the document’s meaning, not from how large the text looks.

Applying an appearance to your own markup

For markup that TextView cannot render — a rich text fragment, an SVG label, or third-party content — apply the appearance class directly. The uit-text-* classes are global, so they work on any element in the toolkit subtree. Use the TextAppearance constant from TypeScript so the class name stays in sync:
import { TextAppearance } from '@wearables-ui-toolkit/mrbd';

<figcaption className={TextAppearance.META2}>Source</figcaption>
Secondary text needs the appearance class and the secondary color utility, because the secondary role carries a required blend as well as a color:
<p className="uit-text-meta2 uit-color-text-secondary">Supporting details</p>

Standard information stacks

These patterns keep text hierarchy consistent across applications. Use the med-lg spacing token between elements unless noted.
Primary stack
  1. TextStyle.HEADING1
  2. TextStyle.BODY1
  3. TextStyle.META1
Start with a body appearance unless the content genuinely needs a dominant heading.
Secondary stack
  1. TextStyle.HEADING2
  2. TextStyle.BODY2
  3. TextStyle.META1
  4. TextStyle.META2
News stack
  1. Eyebrow: TextStyle.META2, secondary color, all caps
  2. Lead: TextStyle.BODY1
  3. Detail: TextStyle.LABEL
  4. Source: TextStyle.META3, secondary color
Use the med-lg spacing token between the outer elements and the xsmall spacing token between lead and detail.

Writing guidance

  • Page header text and metadata are at most two words. Metadata and supported status are optional and appear only when they add high-value context.
  • Subnavigation tab labels are one word.
  • Eyebrows, category labels, and field labels in secondary color are typically all caps; ordinary subtitles stay sentence case.
  • Size layouts for localization and the components’ own line limits, not around one English string.
  • Use one appearance per text element and let it own every font property, which keeps optical alignment intact.
  • Match the HTML element to the document structure so semantics do not depend on visual size.
  • Reserve numeral, display, and heading appearances for dominant information.
  • Use the emphasized variant of the current appearance instead of changing its weight independently.

Avoid

  • Let the appearance own font family, size, weight, line height, and letter spacing instead of setting them separately.
  • Keep custom font properties off elements with an appearance class.
  • Apply exactly one appearance class to each element.
  • Use documented appearances for application text rather than imitating a component’s typography.
  • Customize component text through public props; internal typography is not a supported customization surface.