Skip to content
menumenu tanreiexpand_morecontrasttranslate
tanreiexpand_more
Getting startedWebReactSwiftUIJetpack ComposeFlutterReact NativePresetsYour own design systemUsing Tanrei with AI agentsBrandDesign tokensDesign systems and customizationTheme StudioColorTypographyIconsShapeElevationMotionInteraction statesBehaviourLayoutAccessibilityWordsColor tokensTypescale tokensShape tokensElevation tokensMotion tokensState tokensSpace and measure tokensComponentsButtonMain action buttonSegmented buttonButton groupButton with menuToolbarCopy buttonCheckboxRadio buttonSwitchChipMenuSliderSlider fieldCalendarDateTimePickerField groupRadio groupCheckbox groupSelectSelect fieldMenubarFile uploadFile picker AdvancedDrop zoneText input AdvancedText fieldChip fieldFieldCombobox AdvancedCombobox fieldNumber input AdvancedNumber fieldColor input AdvancedColor fieldOne-time-code input AdvancedOne-time-code fieldEmbedded text input AdvancedChat composerCardDividerModal layer AdvancedDialogListList rowBottom sheetSide sheetCarouselCode blockTablePopoverStepsAccordionDescription listFigureApp shellPage headerTree viewTimelineImage previewHandleResizable frameScroll areaBadgeProgress indicatorMeterNumber tickerLoading indicatorSnackbarTooltipKeyboard shortcutTagInline codeCalloutAvatarEmpty stateTag groupSkeletonFile itemSwatchMarquee textTabsTab viewApp barNavigation barNavigation drawerSearchLinkPaginationPrevious and next linksStepperBreadcrumbsTable of contentsLink cardFAB menuStatusHow Tanrei is builtContributingLicense and attribution
HomeFoundationsColor

Color

Color roles, the monochrome primary, the single accent, and how every scheme is generated and checked.

content_copyView as Markdown

Tanrei never asks a component to pick a color. Components ask for a role, such as primary or surface-container, and the active theme decides which color fills that role. The roles are defined by Tanrei’s vocabulary, and their values by each design system’s layer.

Roles

  • Intents: primary, secondary, and the four status intents error, success, warning and info. Each comes as a set of four: the color, its on- color for content placed on it, a quieter -container, and on-…-container.
  • Surfaces: surface, the five-step surface-container-lowest … surface-container-highest ladder, plus surface-dim and surface-bright. Content on any surface uses on-surface or the quieter on-surface-variant.
  • Outlines: outline and outline-variant (see below).
  • Inverse roles for elements that deliberately flip the theme, such as a snackbar.
  • Fixed roles that keep the same tone in light and dark.
  • Utility: scrim, shadow, focus-ring and the ring and shadow colors used by elevation.

Always pair a fill with its own on- role. That pairing is what the contrast checks guarantee.

A monochrome primary

In the default theme primary is near-black in light mode and near-white in dark mode. The most important action on a screen is therefore the highest-contrast object on it, and it never competes with the product’s own colors. secondary is a softer neutral for supporting actions.

One accent, used sparingly

The accent is not part of the core vocabulary. It is a palette that the default Tanrei system declares (seed #30a3f0), which gives it the same four roles as any intent: accent, on-accent, accent-container, on-accent-container. The core role focus-ring draws from it, and nothing else does: in the default system link takes the primary’s color, and a link is told from the text beside it by its underline. A product declares its own palettes the same way — a brand color that must not be recalculated, or a quiz’s “correct” and “incorrect” — and a preset that imitates Material Design 3 declares tertiary this way rather than Tanrei carrying that slot for everyone. Do not use the accent to decorate; when everything is blue, nothing is.

Outline and outline-variant

The two outline roles look similar and do opposite jobs.

Role Purpose Contrast
outline A functional boundary: the only thing that shows where a control is, as with an empty text field, an unchecked checkbox or an outlined button. At least 3:1 against every surface role
outline-variant A decorative hairline: dividers, card borders, the elevation ring. Removing it must not hide any information. None at standard contrast, where it is a low-alpha black or white. At least 3:1 at medium contrast and 4.5:1 at high, against every surface role, and always weaker than outline

Caution

If a border is the only cue that a control exists, it must use outline. A hairline at 8% alpha is pleasant and invisible to many people.

Contrast levels

Every theme exists at three contrast levels. Standard is the default. Medium and high move content roles toward the extremes and strengthen both outline roles. On the web, high contrast is applied automatically for prefers-contrast: more; the native platforms follow their own system setting. Try it here (the switch applies to the whole page):

Contrast

FilledTonalOutlinedText

How schemes are generated

Colors are not picked by hand. A system file (tokens/systems/core.system.json) declares the palettes — a seed color for the accent and for error, the hue and chroma of the neutrals — and states, as data, which tone of which palette each role takes in light and dark at each contrast level. At build time a generator:

  1. converts each key color into a tonal palette in the HCT color space using the Apache-2.0 material-color-utilities library, where tone maps predictably to contrast;
  2. clamps the neutral palettes to the theme’s chroma, which is zero by default for pure grays;
  3. assigns a tone to every role for light and dark at each contrast level;
  4. writes the result as DTCG files under tokens/generated/.

The generator’s algorithm carries a version (specVersion), so a change to the mapping is a reviewable, deliberate event rather than a silent shift in every color.

Invariants enforced in CI

For all six theme and contrast permutations, the token build fails unless:

  • every (role, on-role) pair reaches 4.5:1, and 7:1 in the two high-contrast schemes;
  • outline reaches 3:1 against every surface role;
  • focus-ring reaches 3:1 against the surfaces it is drawn on.

A threshold may not be loosened to make a build pass. See the full list of roles and values in the color token reference.