Design Tokens

Design tokens are the foundational values that define your app's visual language. PrettyUI provides a comprehensive token system for colors, spacing, border radius, shadows, and typography.

Color Tokens

Color tokens define your app's color palette. Each token has a specific semantic purpose.

Primary & Secondary

TokenPurpose
primaryMain brand color for CTAs, links, active states
primaryForegroundText/icon color on primary backgrounds
secondarySecondary actions, less prominent elements
secondaryForegroundText/icon color on secondary backgrounds
accentHighlights, emphasis, decorative elements
accentForegroundText/icon color on accent backgrounds

Semantic Colors

TokenPurpose
destructiveDestructive actions (delete, remove, errors)
destructiveForegroundText on destructive backgrounds
successSuccess states, confirmations
successForegroundText on success backgrounds
warningWarning states, cautions
warningForegroundText on warning backgrounds

Background & Surface

TokenPurpose
backgroundMain page background
foregroundPrimary text color
mutedSubtle backgrounds (cards, inputs)
mutedForegroundSecondary/muted text
cardCard and surface backgrounds
cardForegroundText on card backgrounds

Border & Focus

TokenPurpose
borderDefault border color
inputInput field borders
ringFocus ring color

Usage Example

struct MyView: View {
    @Environment(\.prettyTheme) private var theme
    @Environment(\.colorScheme) private var colorScheme
    
    var body: some View {
        let colors = theme.colors(for: colorScheme)
        
        VStack {
            Text("Hello")
                .foregroundColor(colors.foreground)
            
            Button("Action") { }
                .background(colors.primary)
                .foregroundColor(colors.primaryForeground)
        }
        .background(colors.background)
    }
}

Spacing Tokens

Spacing tokens provide a consistent scale for padding, margins, and gaps.

TokenValueUsage
xxs2ptMicro spacing, icon gaps
xs4ptTight spacing, small gaps
sm8ptCompact layouts, list items
md16ptDefault spacing, card padding
lg24ptSection spacing, generous padding
xl32ptLarge gaps, section dividers
xxl48ptExtra large spacing
xxxl64ptMaximum spacing, hero sections

Usage Example

VStack(spacing: theme.spacing.md) {
    Text("Title")
        .padding(.horizontal, theme.spacing.lg)
    
    Text("Subtitle")
        .padding(.bottom, theme.spacing.xl)
}
.padding(theme.spacing.md)

Custom Spacing

Use .custom(_:) for one-off values:

.padding(.horizontal, theme.spacing[.custom(20)])

Radius Tokens

Border radius tokens ensure consistent rounded corners across your app.

TokenValueUsage
none0ptSharp corners
sm6ptSmall chips, tags, badges
md10ptInputs, small buttons
lg14ptStandard cards, modals
xl20ptLarge cards, images
xxl28ptSheets, large modals
full9999ptPills, avatars, circular buttons

Usage Example

RoundedRectangle(cornerRadius: theme.radius.lg)
    .fill(colors.card)

// Or using RadiusSize enum
Text("Tag")
    .padding(.horizontal, theme.spacing.sm)
    .background(colors.muted)
    .clipShape(RoundedRectangle(cornerRadius: theme.radius[.sm]))

Shadow Tokens

Shadow tokens create consistent elevation and depth.

TokenRadiusY-OffsetOpacityUsage
none0pt0pt0%No shadow
sm4pt2pt4%Cards at rest
md12pt4pt8%Cards on hover, tooltips
lg20pt8pt10%Floating elements
xl32pt12pt12%Modals, sheets
xxl48pt16pt16%Popovers, dropdowns

Usage Example

Card()
    .prettyShadow(theme.shadows.md)

// Or manually
Card()
    .shadow(
        color: theme.shadows.lg.color,
        radius: theme.shadows.lg.radius,
        x: theme.shadows.lg.x,
        y: theme.shadows.lg.y
    )

Custom Shadows

let customShadow = ShadowStyle(
    color: Color.blue.opacity(0.2),
    radius: 16,
    x: 0,
    y: 8
)

Card()
    .prettyShadow(customShadow)

Typography Tokens

Typography tokens define your app's text styling system.

Font Sizes

TokenSizeUsage
xs12ptCaptions, fine print
sm14ptSecondary text, labels
base16ptBody text (default)
lg18ptEmphasized body text
xl20ptSubtitles
xxl24ptSection titles
xxxl30ptPage titles
display36ptHero headlines

Font Weights

TokenWeight
thin100
light300
regular400
medium500
semibold600
bold700
heavy800

Line Heights

TokenMultiplierUsage
tight1.25Headlines, compact text
normal1.5Body text
relaxed1.75Comfortable reading
loose2.0Maximum readability

Letter Spacing

TokenValueUsage
tighter-0.8ptTight headlines
tight-0.4ptHeadlines
normal0ptBody text
wide0.4ptAll caps text
wider0.8ptSpaced text
widest1.6ptMaximum spacing

Usage Example

Text("Headline")
    .font(.system(size: theme.typography.sizes.xxl))
    .fontWeight(theme.typography.weights.bold)
    .tracking(theme.typography.letterSpacing.tight)

Customizing Tokens

You can customize any token set when creating a custom theme:

extension PrettyTheme {
    static let compact = PrettyTheme(
        spacing: SpacingTokens(
            xxs: 1,
            xs: 2,
            sm: 4,
            md: 8,
            lg: 12,
            xl: 16,
            xxl: 24,
            xxxl: 32
        ),
        radius: RadiusTokens(
            none: 0,
            sm: 4,
            md: 6,
            lg: 8,
            xl: 12,
            xxl: 16,
            full: 9999
        )
    )
}

Best Practices

  1. Use semantic tokens — Prefer colors.primary over hardcoded colors
  2. Stick to the scale — Use existing tokens instead of arbitrary values
  3. Be consistent — Use the same spacing token for similar elements
  4. Use .custom() sparingly — Only for genuinely unique one-off values
  5. Access tokens from theme — Always read from theme.spacing, theme.radius, etc.