Skip to content

@astrolabe/tokens

Neutral --astl-* design tokens with light, dark and high-contrast themes, tokensCss to write them as CSS, the built-in style templates and checkStyleTemplate with its contrast helpers.

Property Modifier Type Description
manifests? readonly readonly object[] Component manifests (tag and cssParts are enough): components and parts must name their tags and parts.
within? readonly readonly StyleTemplateShape[] Templates already applied around this one, e.g. the document's when checking a component template. Default none: the template on top of the plain light and dark themes.

Property Modifier Type Description
at readonly string Where, e.g. name, dark.ink, parts.astl-choice.option.box-shadow, light: ink-muted on surface.
detail readonly string For developers (like checkCatalog in core): English, never shown to students or authors.
kind readonly | "value" | "components" | "name" | "version" | "scopes" | "messages" | "token" | "color" | "property" | "part" | "text-contrast" | "ui-contrast" | "pick-distance" -

The shape of core's StyleTemplate (see @astrolabe/core style.ts for the meaning of each field).

Property Modifier Type
catalogs? readonly readonly TemplateCatalog[]
components? readonly readonly string[]
dark? readonly Readonly<Record<string, string>>
light? readonly Readonly<Record<string, string>>
messages readonly string
name readonly string
parts? readonly Readonly<Record<string, Readonly<Record<string, Readonly<Record<string, string>>>>>>
scopes readonly readonly TemplateScope[]
tokens? readonly Readonly<Record<string, string>>
version readonly number

= core MessageCatalog.

Property Modifier Type
locale readonly string
messages readonly Readonly<Record<string, string>>
namespace readonly string

Property Modifier Type Description
forced readonly ColorScheme System colours used under forced-colors: active.
scale readonly Readonly<Record<ScaleToken, string>> Theme-independent tokens: type, space, radii, widths, durations.
themes readonly Readonly<Record<Theme, ColorScheme>> Colours per theme. hc is black on white: every text pair reaches 7:1.
themeScale readonly Readonly<Record<Theme, Readonly<Record<ThemeScaleToken, string>>>> Theme-dependent non-colour cues. hc marks selected items with a bar at their inline start and bold text, so selection never depends on a native control mark or on colour alone (and never looks like a verdict border).
type ColorScheme = Readonly<Record<ColorToken, string>>;

type ColorToken =
| "canvas"
| "surface"
| "surface-raised"
| "ink"
| "ink-muted"
| "line"
| "outline"
| "accent"
| "on-accent"
| "accent-soft"
| "focus"
| "success"
| "success-soft"
| "on-success"
| "danger"
| "danger-soft"
| "warning"
| "warning-soft"
| "selected"
| "selected-soft"
| PaletteToken;

type PaletteColor = `palette-${PaletteSlot}`;

A colour of the group palette.


type PaletteSlot = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8;

A slot of the group palette.


type PaletteToken =
| PaletteColor
| `${PaletteColor}-soft`;

The group palette: a colour (palette-<n>) and its soft fill (palette-<n>-soft) per slot.


type ScaleToken =
| "font-body"
| "font-display"
| "font-mono"
| "size-content"
| "size-ui"
| "size-small"
| "line-height-content"
| "space-1"
| "space-2"
| "space-3"
| "space-4"
| "space-5"
| "space-6"
| "space-7"
| "space-8"
| "radius-s"
| "radius-m"
| "radius-l"
| "radius-pill"
| "outline-width"
| "focus-width"
| "focus-offset"
| "target-min"
| "duration-fast"
| "duration-normal"
| "separator-display";

type TemplateScope = "document" | "component";

= core StyleScope.


type TemplateTheme = "light" | "dark";

Themes a template changes: never hc.


type Theme = "light" | "dark" | "hc";

Neutral, brand-free design tokens. Every value becomes a CSS custom property --astl-<name>. Hosts brand the player by overriding these properties, never by styling internals.


type ThemeScaleToken = "selected-bar" | "selected-weight";

Non-colour values that change with the theme.


type ThemeSetting = Theme | "auto";

auto follows prefers-color-scheme (light or dark).


type TokenName =
| ColorToken
| ScaleToken
| ThemeScaleToken;
const builtInStyleTemplates: readonly StyleTemplateShape[];

playful and notebook, usable on documents and on every component. The default look is no template at all.


const PALETTE: readonly PaletteColor[];

The group palette in slot order: eight colours that tell groups apart (categories, pairs, zones, joined lines, found words, regions). Give groups the slots in order and start again after the eighth; each colour has a soft fill, --astl-palette-<n>-soft, for backgrounds.

  • Never red or green, the verdict colours: every slot stays at least 15 (CIEDE2000) from success and danger, and at least 10 from the partial amber (warning).
  • Neighbours stay apart for red-green colour blindness (protanopia, deuteranopia), also the eighth and the first: warm and cool slots alternate.
  • Each colour reads as text on the page and surface backgrounds (4.5:1, 7:1 in hc), and so do ink, ink-muted and the colour itself on its soft fill.
  • Colour never carries meaning alone: groups also differ by their label or a pattern. Under forced colours the palette gives way to system colours (CanvasText, and Canvas for the soft fills).

const PART_PROPERTIES: ReadonlySet<string>;

CSS properties a template may set on ::part(): shape, spacing and type. Outer ::part() rules beat a component's own styles, so borders, outlines, colours, display and text size stay out: they carry verdicts, focus rings, selection and contrast. The player drops every other property.


const TEMPLATE_NAME: RegExp;

= core STYLE_TEMPLATE_NAME: lowercase kebab-case, 1 to 40 characters, starting with a letter.


const TEXT_PAIRS: readonly (readonly [ColorToken, ColorToken])[];

Text (foreground) on background pairs the themes guarantee: 4.5:1, and 7:1 in hc. Built by a pure call, so a bundle that does not use the list (the player) leaves it out.


const THEMES: readonly Theme[];

const tokens: Tokens;

const UI_PAIRS: readonly (readonly [ColorToken, ColorToken])[];

Non-text pairs (control borders, focus rings, verdict borders) the themes guarantee: 3:1. Pure, as above.

function checkStyleTemplate(template, options?): StyleTemplateProblem[];

Problems of a template: name, version, scopes, component tags, messages, token names, values that are unsafe, colours that are not #rgb / #rrggbb, targets, focus rings, control borders and text sizes under their accessible minimum (MINIMUM_PX), part properties and names, picks next to the verdict colours (PICK_DISTANCE), and contrast. Contrast: every TEXT_PAIRS pair at least 4.5:1 and every UI_PAIRS pair at least 3:1 in light and dark after applying the template (on top of within); for templates with the component scope also against the enclosing scope's backgrounds, which show through where a component paints none. An empty list means the template is fine.

Parameter Type
template StyleTemplateShape
options? CheckStyleTemplateOptions

StyleTemplateProblem[]


function contrastRatio(a, b): number;

WCAG 2 contrast ratio (1 to 21) of two #rgb or #rrggbb colours. Throws a TypeError for other formats.

Parameter Type
a string
b string

number


function isSafeStyleValue(value): boolean;

Whether a value can go into a generated declaration without ending it, its rule or a <style>: no { } ; < >, no comment opener, no backslash (an escape could swallow the ; after it), no line breaks, closed quotes and balanced ( ) and [ ] outside them (an open calc( would swallow everything after it), not blank.

Parameter Type
value string

boolean


function templateColors(theme, templates): ColorScheme;

The colours of the light or dark theme with templates applied in order, e.g. [documentTemplate, componentTemplate]: each template's tokens, then its light or dark values. Non-colour tokens are ignored.

Parameter Type
theme TemplateTheme
templates readonly StyleTemplateShape[]

ColorScheme


function tokensCss(selector): string;

The token stylesheet for selector (comma-separated selectors allowed, :host included): light by default, data-theme="dark" | "hc" themes, data-theme="auto" following prefers-color-scheme, system colours under forced-colors: active and no motion under prefers-reduced-motion: reduce.

Parameter Type
selector string

string