Skip to content

For Product Engineers

Who this is for. The engineer whose primary responsibility is shipping product features in a consuming repo (sageox-mono, sageox/speaker, sageox/ox, etc.). You consume tokens, components, and lint rules from sageox-design; you don't usually author them. You're still a builder — you write the production UI code that ships to customers, and you have commit access to the harness when a gap blocks you.

Sister pages: for design engineers (refining the harness itself) · for product owners (voice, tone, density). For the design-engineering practice (two loops, how new tokens get proposed) see HARNESS.md.

This page is the technical reference for consuming SageOx design tokens in code: install, imports, semantic tokens, theme switching, integration patterns.


Installation

npm install @sageox/design

Usage

TypeScript/JavaScript

import { lightTheme, darkTheme, sageoxPalette } from '@sageox/design'

// Access theme values
const primaryButton = lightTheme.button.primary.bg // "#7fa87c"
const surfaceColor = darkTheme.surface[1].value // "var(--ox-crater-900)"

CSS Custom Properties

@import '@sageox/design/css/tokens.css';

.card {
  background: var(--ox-dust-50);
  color: var(--ox-silt-900);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
}

CSS with Semantic Tokens

.card {
  background: var(--ox-surface-selected);
  color: var(--ox-text-primary);
  border: 1px solid var(--ox-border-subtle);
}

.button-primary {
  background: var(--ox-sage-700); /* deep sage — light-mode CTA */
  color: #ffffff;                 /* white label (~4.6:1); dark mode: sage-400 bg + crater-800 label */
}

Token Structure

tokens/
├── colors.yaml      # Brand + semantic palettes
├── themes.yaml      # Light/dark theme mappings + semantic aliases
├── spacing.yaml     # Spacing, radius, shadows, motion
└── typography.yaml  # Font stacks, sizes, weights

Platform Outputs

Platform Format Path
Web CSS, TypeScript platforms/web/
CLI TOML, Go platforms/cli/
Mobile TypeScript platforms/mobile/
GitLab CSS/Stylus platforms/gitlab/

Naming Convention

--ox-{category}-{scale|variant}

Examples:
--ox-sage-500         # Brand color, scale 500
--ox-crater-900       # Dark surface, scale 900
--ox-silt-900         # Text color, scale 900
--ox-success-500      # Semantic color
--ox-surface-quiet    # Semantic alias
--ox-text-primary     # Semantic alias

Theme Switching

/* Light mode (default) — surfaces = Dust, text = Silt */
:root {
  --ox-surface-quiet: var(--ox-dust-100);
  --ox-text-primary: var(--ox-silt-900);
}

/* Dark mode — surfaces = Crater, text = Dust */
.dark,
[data-theme="dark"] {
  --ox-surface-quiet: var(--ox-crater-900);
  --ox-text-primary: var(--ox-dust-100);
}

Source of Truth

Question Source
What colors exist? tokens/colors.yaml
What does the light theme use? tokens/themes.yaml
What spacing values exist? tokens/spacing.yaml
What animations are available? tokens/spacing.yaml → animation

Common Patterns

Hover State

.interactive {
  transition: var(--transition-fast);
}
.interactive:hover {
  background: var(--ox-surface-elevated);
  transform: translateY(-2px);
}

Focus Ring

.focusable:focus-visible {
  outline: 2px solid var(--ox-border-focus);
  outline-offset: 2px;
}

Disabled State

.disabled {
  opacity: var(--ox-interaction-disabled-opacity);
  pointer-events: none;
}

Building from Source

# Install dependencies
npm install

# Compile tokens to all platforms
npm run compile

# Watch for changes
npm run watch

Integration Examples

React

import { useTheme } from '@sageox/design/react'

function Button({ children }) {
  const theme = useTheme()
  return (
    <button style={{
      background: theme.button.primary.bg,
      color: theme.button.primary.text,
    }}>
      {children}
    </button>
  )
}

Tailwind CSS

// tailwind.config.js
import { colors, spacing } from '@sageox/design/tailwind'

export default {
  theme: {
    extend: {
      colors,
      spacing,
    },
  },
}