Design Tokens
read as.mdEvery @ggui-ai/design primitive — and by extension every gadget that ships with the OSS renderer — reads its visual state from DTCG tokens exposed as CSS custom properties. Tokens themselves need no runtime: override the variables on any ancestor and the cascade does the rest on the next paint.
Operator theming builds on these same variables: ggui.json#theme selects one of the shipped presets (or a DTCG file), and per-app overlays are validated --ggui-* maps injected after the base token block, so a partial overlay keeps token defaults. Agents can enumerate presets with ggui_list_themes and pick one per render via ggui_render({themeId}) — see Custom Theming.
/* Every primitive uses var(--ggui-…) with a hardcoded fallback */color: var(--ggui-color-primary-600, #0284c7);padding: var(--ggui-spacing-md, 16px);border-radius: var(--ggui-shape-radius-md, 8px);Colors
Section titled “Colors”Color Palettes
Section titled “Color Palettes”Primary (Sky Blue)
Gray
Success
Warning
Error
Info
Semantic Colors
Section titled “Semantic Colors”These tokens map to specific UI roles and adapt between light and dark themes.
Material Role Pairs
Section titled “Material Role Pairs”The canonical theme states its layering as role pairs — a background and the ink that sits on it. A theme.json authors three of the four (ground, container, sunken, each with its on*); elevated is derived. Primitives use these to keep contrast right across nested backgrounds.
| CSS variable | Role |
|---|---|
--ggui-color-ground |
The canvas — page / sheet background |
--ggui-color-onGround |
Primary text and icons on ground |
--ggui-color-container |
Cards, panels, filled containers |
--ggui-color-onContainer |
Text/icons on container |
--ggui-color-elevated |
Raised surfaces (menus, popovers) — derived, not authored |
--ggui-color-onElevated |
Text/icons on elevated — derived |
--ggui-color-sunken |
Wells, inputs at rest, code blocks — recessed inside container |
--ggui-color-onSunken |
Secondary text/icons on sunken |
--ggui-color-outline |
Standard borders + dividers |
--ggui-color-outlineVariant |
Faint borders, disabled outlines |
--ggui-color-onPrimary |
Text/icons on a primary fill (CTA labels) |
--ggui-color-primaryContainer |
Tinted primary container (soft CTA, highlight) |
--ggui-color-onPrimaryContainer |
Text/icons on primaryContainer |
--ggui-color-onError |
Text/icons on an error fill |
--ggui-color-errorContainer |
Softer error container (inline error banners) |
--ggui-color-onErrorContainer |
Text/icons on errorContainer |
--ggui-color-tertiary |
Complementary accent to primary |
--ggui-color-onTertiary |
Text/icons on a tertiary fill |
--ggui-color-tertiaryContainer |
Tinted tertiary container |
--ggui-color-onTertiaryContainer |
Text/icons on tertiaryContainer |
Spacing
Section titled “Spacing”A consistent spacing scale ensures visual rhythm across all components.
xs4px--ggui-spacing-xssm8px--ggui-spacing-smmd16px--ggui-spacing-mdlg24px--ggui-spacing-lgxl32px--ggui-spacing-xl2xl48px--ggui-spacing-2xl3xl64px--ggui-spacing-3xlTypography
Section titled “Typography”Canonical theme path: font.{family,weight,ramp,letterSpacing} — a theme authors the families, the weights, one font.ramp and optional letter-spacing; the size and line-height scales are derived from the ramp. Emitted as --ggui-font-family-*, --ggui-font-weight-*, and the derived --ggui-font-size-* / --ggui-font-lineHeight-* shown below. Web fonts are declared as typography.faces (https: sources only); ggui deploy names any family the hosted path does not deliver yet. Authored font.size or font.lineHeight is refused.
Font Families
Font Sizes
xs12px--ggui-typography-fontSize-xssm14px--ggui-typography-fontSize-smbase16px--ggui-typography-fontSize-baselg18px--ggui-typography-fontSize-lgxl20px--ggui-typography-fontSize-xl2xl24px--ggui-typography-fontSize-2xl3xl30px--ggui-typography-fontSize-3xl4xl36px--ggui-typography-fontSize-4xlFont Weights
NormalThe quick brown fox jumps over the lazy dog400MediumThe quick brown fox jumps over the lazy dog500SemiboldThe quick brown fox jumps over the lazy dog600BoldThe quick brown fox jumps over the lazy dog700Line Heights
TightNormalRelaxedBorder Radius
Section titled “Border Radius”Canonical theme path: shape.radius.*. Emitted as --ggui-shape-radius-{none,sm,md,lg,xl,2xl,full}.
--ggui-shape-radius-none--ggui-shape-radius-sm--ggui-shape-radius-md--ggui-shape-radius-lg--ggui-shape-radius-xl--ggui-shape-radius-2xl--ggui-shape-radius-fullShadows
Section titled “Shadows”Canonical theme path: shape.shadow.*. Emitted as --ggui-shape-shadow-{none,xs,sm,md,lg,xl,2xl}.
Motion
Section titled “Motion”The canonical motion group covers durations, easings, keyframes, and ready-made transition shorthands. Durations + transitions both surface as CSS custom properties; transitions are pre-composed so primitives can drop in a single var(--ggui-motion-transition-…) without rewriting the curve.
| Variable | Typical value | When to use |
|---|---|---|
--ggui-motion-duration-instant |
0ms |
Immediate state flips (no animation) |
--ggui-motion-duration-fast |
100ms |
Hover, focus, small icon swaps |
--ggui-motion-duration-normal |
200ms |
Default for color/opacity transitions |
--ggui-motion-duration-slow |
300ms |
Layout shifts, large fades |
--ggui-motion-duration-slower |
500ms |
Full-surface transitions, long fades |
--ggui-motion-transition-fast |
100ms cubic-bezier(0.4, 0, 0.2, 1) |
Duration + curve only; you name the property |
--ggui-motion-transition-normal |
200ms cubic-bezier(0.4, 0, 0.2, 1) |
Duration + curve only; you name the property |
--ggui-motion-transition-slow |
300ms cubic-bezier(0.4, 0, 0.2, 1) |
Duration + curve only; you name the property |
--ggui-motion-transition-colors |
color/background-color/border-color 200ms |
Theme-aware color changes |
--ggui-motion-transition-opacity |
opacity 200ms |
Fades, show/hide |
--ggui-motion-transition-transform |
transform 200ms |
Translate/scale interactions |
There is no catch-all all transition — name the properties you move, or use one of the bare fast / normal / slow shorthands. Under prefers-reduced-motion: reduce, fall back to var(--ggui-accessibility-reducedMotion-duration) (0ms) instead of the durations above.
Accessibility
Section titled “Accessibility”Top-level accessibility tokens make a11y intent explicit instead of leaving it implicit in component styles. They emit as --ggui-accessibility-* and pair with the standard media queries.
focusRing, reducedMotion, and highContrast are token groups, not scalars — each leaf emits its own variable, so there is no bare --ggui-accessibility-focusRing.
| Variable | Type | Notes |
|---|---|---|
--ggui-accessibility-focusRing-color |
color | Focus-indicator color used by every primitive |
--ggui-accessibility-focusRing-width |
dimension | Ring thickness (2px in the canonical theme) |
--ggui-accessibility-focusRing-offset |
dimension | Gap between the element and the ring |
--ggui-accessibility-reducedMotion-duration |
duration | Duration to use under prefers-reduced-motion: reduce |
--ggui-accessibility-highContrast-borderWidth |
dimension | Border thickness under prefers-contrast: more |
--ggui-accessibility-highContrast-textColor |
color | Text color under prefers-contrast: more |
--ggui-accessibility-highContrast-backgroundColor |
color | Background under prefers-contrast: more |
--ggui-accessibility-highContrast-linkColor |
color | Link color under prefers-contrast: more |
Override the focusRing group at the theme level to brand the focus indicator across every primitive at once.
Z-Index
Section titled “Z-Index”A canonical layering scale prevents floating UIs from fighting each other. Values are unitless integers and increase with elevation.
| Variable | Layer | Typical occupant |
|---|---|---|
--ggui-zIndex-hide |
-1 |
Off-screen / underlay |
--ggui-zIndex-base |
0 |
Page content |
--ggui-zIndex-docked |
10 |
Docked sidebars, sticky toolbars |
--ggui-zIndex-dropdown |
1000 |
Menus, select popovers |
--ggui-zIndex-sticky |
1100 |
Sticky table headers |
--ggui-zIndex-banner |
1200 |
Announcement / cookie banners |
--ggui-zIndex-overlay |
1300 |
Backdrop scrims |
--ggui-zIndex-modal |
1400 |
Modal dialogs |
--ggui-zIndex-popover |
1500 |
Floating popovers anchored to content |
--ggui-zIndex-skipLink |
1600 |
Keyboard skip-link (must beat modals) |
--ggui-zIndex-toast |
1700 |
Toast notifications |
--ggui-zIndex-tooltip |
1800 |
Tooltips (topmost interactive element) |
Using Tokens
Section titled “Using Tokens”In primitives
Section titled “In primitives”Nothing to wire — every primitive already consumes the tokens:
import { Button, Card, Input } from '@ggui-ai/design';
<Card> <Input placeholder="Enter your name" /> <Button variant="primary">Submit</Button></Card>;In your own components
Section titled “In your own components”Reference tokens by their CSS variable, with a hardcoded fallback for environments where the theme provider hasn’t loaded yet:
.my-component { background: var(--ggui-color-ground, #ffffff); padding: var(--ggui-spacing-md, 16px); border-radius: var(--ggui-shape-radius-lg, 12px); box-shadow: var(--ggui-shape-shadow-md, 0 8px 16px -4px rgba(15, 23, 42, 0.10)); font-family: var(--ggui-font-family-sans, system-ui, -apple-system, sans-serif); font-size: var(--ggui-font-size-sm, 14px); color: var(--ggui-color-onGround, #111827); transition: var(--ggui-motion-transition-colors, color 200ms ease);}Theming
Section titled “Theming”Override on any element — :root for global, a wrapper for per-subtree:
:root { --ggui-color-primary-600: #7c3aed; /* Purple instead of sky blue */ --ggui-color-ground: #fefce8; /* Warm paper canvas */ --ggui-color-onGround: #1f1410; /* Ink for the new ground */ --ggui-shape-radius-md: 16px; /* Pillier corners */ --ggui-motion-duration-normal: 240ms; /* Slightly more deliberate */}See Custom Theming for the full recipe — global overrides, dark-mode pairs, and scoped subtrees.