-
Notifications
You must be signed in to change notification settings - Fork 0
Design Tokens
A complete reference of all design tokens in layrz_ui. This is the source of truth for semantic color, typography, spacing, radius, shadow, border, and motion values.
All colors are defined for light mode only. See decision D7 for details.
Access via context.theme.tokens.colors or context.tokenizer.colors.
| Token | Value | Hex | Usage |
|---|---|---|---|
primary |
Deep navy blue (customizable) | #001E60 |
Interactive elements, prominent actions, primary brand |
Default: customizable via LayrzThemeData.light(primaryColor: ...).
| Token | Value | Hex | Usage |
|---|---|---|---|
background |
Light gray | #FCFCFC |
Canvas/scaffold background |
surface |
White | #FFFFFF |
Cards, dialogs, elevated containers |
surface2 |
Light gray 2 | #F7F7F7 |
Nested containers, popovers |
surface3 |
Light gray 3 | #F0F0F0 |
Deepest nesting surface color |
| Token | Value | Hex | Usage |
|---|---|---|---|
fg1 |
Very dark navy | #1A1A2E |
Highest-contrast text (labels, body) |
fg2 |
Dark gray | #4A4A5A |
Secondary text, borders |
fg3 |
Medium gray | #9E9E9E |
Placeholders, disabled text, hints |
fg4 |
Light gray | #C4C4C4 |
Very subtle text, lowest contrast |
| Token | Value | Hex | Usage |
|---|---|---|---|
danger |
Red | #E53935 |
Errors, destructive actions, critical alerts |
success |
Green | #43A047 |
Positive confirmations, valid input, good status |
warning |
Orange | #FB8C00 |
Cautions, non-critical alerts, warnings |
info |
Blue | #1E88E5 |
Informational and neutral alerts |
| Token | Value | Hex | Usage |
|---|---|---|---|
contextual |
Medium gray | #9E9E9E |
Neutral status, informational elements |
divider |
Light gray | #E0E0E0 |
Borders, dividers, separator lines |
overlay |
Black @ 50% | #00000080 |
Modal scrims, overlay backgrounds |
| Token | Value | Usage |
|---|---|---|
tonalOpacity |
0.2 (20%) | Alpha value applied to tonal/filledTonal fills to create visual distinction |
Access via context.theme.tokens.typography or context.theme.textTheme.
All text styles use Open Sans by default (customizable via font parameters in LayrzThemeData.light()). Font color is always fg1 (highest-contrast text).
| Style | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
displayLarge |
57 | normal (400) | 1.17 | −0.25 | Large headlines (h1) |
displayMedium |
45 | normal | 1.16 | 0.0 | Major section headers |
displaySmall |
36 | normal | 1.22 | 0.0 | Secondary headlines |
| Style | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
headlineLarge |
32 | normal | 1.25 | 0.0 | Section headers (h2) |
headlineMedium |
28 | normal | 1.29 | 0.0 | Subsection headers (h3) |
headlineSmall |
24 | normal | 1.33 | 0.0 | Card titles, list headers |
| Style | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
titleLarge |
22 | bold (600) | 1.27 | 0.0 | Prominent titles, dialog headers |
titleMedium |
16 | bold | 1.5 | 0.15 | Item titles, field labels |
titleSmall |
14 | bold | 1.43 | 0.1 | Small titles, badges |
| Style | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
bodyLarge |
16 | normal | 1.5 | 0.15 | Paragraph text, UI copy |
bodyMedium |
14 | normal | 1.43 | 0.25 | Default root text style |
bodySmall |
12 | normal | 1.33 | 0.4 | Secondary UI text, captions |
| Style | Size | Weight | Line Height | Letter Spacing | Usage |
|---|---|---|---|---|---|
labelLarge |
14 | bold | 1.43 | 0.1 | Button labels, form labels |
labelMedium |
12 | bold | 1.33 | 0.5 | Small labels, tags |
labelSmall |
11 | bold | 1.45 | 0.5 | Tiny labels, badges |
Access via context.theme.tokens.spacing or context.tokenizer.spacingTokens.
All values are in logical pixels. The base unit is 8.0 pixels.
| Token | Value | Usage |
|---|---|---|
base |
8.0 | Base spacing unit, used by convenience methods |
sp4 |
4.0 | Extra-small gaps |
sp6 |
6.0 | Small gaps |
sp8 |
8.0 | Small gaps (matches base) |
sp10 |
10.0 | Small-medium gaps |
sp12 |
12.0 | Medium gaps |
sp14 |
14.0 | Medium gaps |
sp16 |
16.0 | Standard padding / margin |
sp20 |
20.0 | Large padding |
sp24 |
24.0 | Large padding |
sp28 |
28.0 | Large padding |
sp32 |
32.0 | Large padding |
sp36 |
36.0 | Extra-large padding |
sp40 |
40.0 | Extra-large padding |
sp44 |
44.0 | Extra-large padding (touch target size) |
sp48 |
48.0 | Extra-large padding |
// These use the base unit (8.0)
context.tokens.spacing.margin // EdgeInsets.all(8)
context.tokens.spacing.reducedMargin // EdgeInsets.all(4)
context.tokens.spacing.padding // EdgeInsets.all(8)
context.tokens.spacing.sizedBox // SizedBox(8x8)
context.tokens.spacing.spacingSize // Size(8, 8)Access via context.theme.tokens.radius or context.tokenizer.radiusTokens.
All values are in logical pixels. The base unit is 8.0 pixels.
| Token | Value | Usage |
|---|---|---|
base |
8.0 | Base radius, used by convenience methods and most containers |
r8 |
8.0 | Standard corner rounding |
r10 |
10.0 | Slightly more rounded |
r12 |
12.0 | Medium rounding |
r14 |
14.0 | Medium-large rounding |
r16 |
16.0 | Large rounding |
r20 |
20.0 | Extra-large rounding |
r24 |
24.0 | Extra-large rounding |
full |
999.0 | Pill shape (fully rounded) |
// These use the base unit (8.0)
context.tokens.radius.borderRadius // BorderRadius.circular(8)For nested container borders, compute the inner radius using:
context.tokenizer.innerRadius(
outerRadius: 12.0,
spacer: 4.0,
)This returns BorderRadius.circular(8.0) because inner = outer − spacer = 12 − 4 = 8.
Rule: The inner corner arc must share the outer arc's centre. The spacer represents the distance between the two arcs' centres; subtracting it from the outer radius gives the inner radius. If the result is negative (e.g., outerRadius: 4, spacer: 10), it clamps to 0, producing a pill shape.
Access via context.theme.tokens.shadow or context.tokenizer.shadowTokens.
Shadow tokens map elevation levels (0–5) to BoxShadow lists. The algorithm computes blur radius, opacity, and offset based on elevation to create visual hierarchy.
- Opacity: Linear interpolation from 0.06 (elevation 0) to 0.12 (elevation 5)
-
Blur Radius:
3 × elevation + 2 -
Vertical Offset:
elevation − 1pixels downward
| Token | Elevation | Usage |
|---|---|---|
elevation1 |
1 | Subtle elevation, cards |
elevation2 |
2 | Standard elevation, popovers |
elevation3 |
3 | Medium elevation, overlays |
elevation4 |
4 | High elevation, modal dialogs |
elevation5 |
5 | Highest elevation, top-most overlays |
Example:
context.tokens.shadow.elevation2
// Returns: [BoxShadow(color: black@9%, blur: 8, offset: Offset(0, 1))]For custom elevation settings:
context.tokenizer.shadow(
elevation: 2, // 0–5 (required)
radius: 12.0, // Custom border radius (optional, defaults to base)
color: Colors.white, // Surface color (optional, defaults to surface)
shadowColor: Colors.black, // Shadow color (optional)
reverse: false, // Flip offset for pressed state (optional)
hideOnElevationZero: false, // Hide shadow at elevation 0 (optional)
)Returns a BoxDecoration with:
- The specified surface color and border radius
- Computed box shadow for the elevation
- At elevation 0: a 1-pixel outline border (unless
hideOnElevationZero: true)
Example: Pressed Button State:
context.tokenizer.shadow(elevation: 2, reverse: true)
// Reverses the shadow offset for a "pressed" visual effectAccess via context.theme.tokens.border.
Border tokens define stroke widths and pre-built BorderSide objects.
| Token | Value | Usage |
|---|---|---|
base |
1.5 | Default border width |
stroke1 |
1.0 | Thin stroke |
stroke2 |
2.0 | Medium stroke |
stroke3 |
3.0 | Thick stroke |
| Property | Value | Usage |
|---|---|---|
light |
BorderSide(color: divider, width: 1.0) |
Thin divider lines |
normal |
BorderSide(color: divider, width: 2.0) |
Standard borders |
thick |
BorderSide(color: divider, width: 3.0) |
Prominent borders |
Example:
Container(
decoration: BoxDecoration(
border: Border(bottom: context.tokens.border.normal),
),
)Access via context.theme.tokens.motion or context.tokenizer.motion.
Motion tokens define animation durations and easing curves.
| Token | Value | Usage |
|---|---|---|
dHover |
100ms | Hover state transitions |
dPress |
80ms | Press/tap feedback |
dTransition |
200ms | Component state changes |
dPageTransition |
250ms | Page navigation |
dDialog |
300ms | Dialog entrance/exit |
| Token | Value | Usage |
|---|---|---|
easing |
Curves.easeInOut |
Standard animations |
easingEnter |
Curves.easeOut |
Entrance animations (fast start) |
easingExit |
Curves.easeIn |
Exit animations (slow start) |
Example:
AnimatedOpacity(
duration: context.tokens.motion.dTransition,
curve: context.tokens.motion.easing,
opacity: isHovered ? 1.0 : 0.5,
child: MyWidget(),
)context.theme.tokens.colors.primary
context.tokens.colors.primary
context.tokenizer.primaryAll three patterns are equivalent but offer different levels of brevity.
final theme = LayrzTheme.of(context);
final primary = theme.tokens.colors.primary;final tokens = context.tokens;
final primary = tokens.colors.primary;Modify tokens via LayrzThemeData.copyWith() and LayrzTokens.copyWith():
final customTheme = theme.copyWith(
tokens: theme.tokens.copyWith(
colors: theme.tokens.colors.copyWith(
primary: const Color(0xFF0077BE),
danger: const Color(0xFFD32F2F),
),
spacing: theme.tokens.spacing.copyWith(
sp16: 18.0, // Increase standard padding
),
),
);Then pass the custom theme to LayrzApp:
LayrzApp(
theme: customTheme,
// ...
)- D7: Light Mode Only — Explains why dark mode is not supported.
- D15: Interaction States Never Change Geometry — States that hover/press/focus do not change size, padding, or layout; only visual properties like color and opacity.
Last updated: 2026-08-13
Related pages: Theming, LayrzTokenizer, Getting-Started, Architecture
Made with ❤️ by Golden M, Inc.