Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.vertz.dev/llms.txt

Use this file to discover all available pages before exploring further.

Vertz provides scoped, utility-driven styling with css() for component styles, variants() for parameterized variants, globalCss() for resets and base styles, and font() + compileFonts() for font management.

css()

Define scoped style blocks. Returns an object with class name strings keyed by block name.
import { css, token } from '@vertz/ui/css';

const styles = css({
  card: {
    backgroundColor: token.color.background,
    borderRadius: token.radius.lg,
    boxShadow: token.shadow.md,
    padding: token.spacing[6],
  },
  title: {
    fontSize: token.font.size.xl,
    fontWeight: token.font.weight.bold,
    color: token.color.foreground,
  },
});

// styles.card → '_a1b2c3' (scoped class name)
// styles.title → '_d4e5f6'
// styles.css → compiled CSS string (non-enumerable)

function TaskCard() {
  return (
    <div className={styles.card}>
      <h2 className={styles.title}>Task</h2>
    </div>
  );
}

Signature

function css<T extends CSSInput>(input: T, filePath?: string): CSSOutput<T>;

Parameters

ParameterTypeDescription
inputCSSInputObject mapping block names to StyleBlock objects
filePathstringUsed internally by the compiler for scoping

Returns

CSSOutput<T> — object with each block name mapped to its scoped class name string, plus a non-enumerable css property containing the compiled CSS.

Style blocks

Each block value is a StyleBlock — an object of camelCase CSS properties. Numeric values get px auto-appended for length properties, or pass through raw for unitless properties (lineHeight, opacity, zIndex, etc.). Nested selectors use & for pseudo-classes / child combinators and @ for at-rules:
const styles = css({
  button: {
    display: 'inline-flex',
    alignItems: 'center',
    padding: token.spacing[2],
    backgroundColor: token.color.primary,
    color: token.color['primary-foreground'],
    '&:hover': {
      backgroundColor: token.color['primary-700'],
    },
    '&:disabled': {
      opacity: 0.5,
      cursor: 'not-allowed',
    },
    '@media (min-width: 640px)': {
      padding: token.spacing[4],
    },
  },
});

Design tokens

Use token.* for theme-aware values (colors, spacing, radius, shadow, font). Tokens compile to CSS custom properties backed by your theme.
import { token } from '@vertz/ui/css';

const styles = css({
  hero: {
    backgroundColor: token.color.background,
    color: token.color.foreground,
    padding: token.spacing[8],
    borderRadius: token.radius.xl,
    fontSize: token.font.size['2xl'],
    fontWeight: token.font.weight.semibold,
  },
});

Type safety

CSS property names are validated against the full CSS property set. Typos produce TypeScript errors:
// ❌ Type error — 'bacgroundColor' is not a valid CSS property
css({
  card: { bacgroundColor: 'red' },
});
Validation runs in both top-level and nested selector blocks.

variants()

Create a typed variant function for component styling with multiple visual states.
import { variants, token } from '@vertz/ui/css';

const button = variants({
  base: {
    display: 'inline-flex',
    alignItems: 'center',
    borderRadius: token.radius.md,
    fontWeight: token.font.weight.medium,
  },
  variants: {
    intent: {
      primary: {
        backgroundColor: token.color.primary,
        color: token.color['primary-foreground'],
      },
      danger: {
        backgroundColor: token.color.destructive,
        color: token.color['destructive-foreground'],
      },
      ghost: {
        backgroundColor: 'transparent',
        color: token.color.foreground,
      },
    },
    size: {
      sm: { fontSize: token.font.size.xs, paddingInline: token.spacing[3] },
      md: { fontSize: token.font.size.sm, paddingInline: token.spacing[4] },
      lg: { fontSize: token.font.size.base, paddingInline: token.spacing[6] },
    },
  },
  defaultVariants: { intent: 'primary', size: 'md' },
});

// button() → '_base _primary _md'
// button({ intent: 'danger', size: 'sm' }) → '_base _danger _sm'

function SubmitButton() {
  return <button className={button({ intent: 'primary', size: 'lg' })}>Save</button>;
}

Signature

function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;

VariantsConfig

PropertyTypeDescription
baseStyleBlockBase styles applied to all variants
variantsVObject mapping variant names to option → StyleBlock maps
defaultVariantsPartial<V>Default variant selections when not specified
compoundVariantsCompoundVariant<V>[]Styles applied when specific variant combinations are active

Returns

VariantFunction<V> — a callable function that accepts variant props and returns a class name string. Also has a .css property with the compiled CSS.

Compound variants

const badge = variants({
  base: {
    borderRadius: token.radius.full,
    paddingInline: token.spacing[2],
    fontSize: token.font.size.xs,
  },
  variants: {
    color: {
      blue: { backgroundColor: token.color['blue-100'], color: token.color['blue-800'] },
      red: { backgroundColor: token.color['red-100'], color: token.color['red-800'] },
    },
    outlined: {
      true: { backgroundColor: 'transparent', borderWidth: '1px' },
      false: {},
    },
  },
  compoundVariants: [
    {
      color: 'blue',
      outlined: true,
      styles: { borderColor: token.color['blue-300'], color: token.color['blue-700'] },
    },
    {
      color: 'red',
      outlined: true,
      styles: { borderColor: token.color['red-300'], color: token.color['red-700'] },
    },
  ],
  defaultVariants: { color: 'blue', outlined: false },
});

globalCss()

Define global styles — resets, base typography, body defaults. Properties use camelCase, converted to kebab-case in output.
import { globalCss } from '@vertz/ui/css';

const reset = globalCss({
  '*': { margin: '0', padding: '0', boxSizing: 'border-box' },
  body: { fontFamily: 'system-ui, sans-serif', lineHeight: '1.5' },
  a: { textDecoration: 'none', color: 'inherit' },
});

// reset.css → compiled global CSS string

Nested at-rules

@keyframes, @media, and @supports accept a nested block — the inner keys are frame selectors (from, to, 0%100%) or regular selectors, and their values are CSS declarations.
globalCss({
  '@keyframes spin': {
    from: { transform: 'rotate(0deg)' },
    to: { transform: 'rotate(360deg)' },
  },
  '@media (min-width: 768px)': {
    body: { fontSize: '18px' },
  },
});

Signature

function globalCss(input: GlobalCSSInput): GlobalCSSOutput;

Parameters

ParameterTypeDescription
inputGlobalCSSInputSelector → block. Block is CSS declarations or (for at-rules) a map of nested selectors to declarations.

Returns

GlobalCSSOutput — object with a css property containing the compiled CSS string.

font()

Create a font descriptor that describes a font family and its sources. Only woff2 format is supported.
import { font } from '@vertz/ui/css';

const sans = font('DM Sans', {
  weight: '100..1000',
  src: '/fonts/dm-sans.woff2',
  fallback: ['system-ui', 'sans-serif'],
});

Parameters

ParameterTypeDescription
familystringThe font family name (e.g., 'DM Sans')
optionsFontOptionsFont configuration (see types below)

Returns

FontDescriptor — a branded object describing the font, for use with compileFonts().

compileFonts()

Compile font descriptors into @font-face CSS, CSS custom properties, and preload link tags.
import { font, compileFonts } from '@vertz/ui/css';

const sans = font('DM Sans', {
  weight: '100..1000',
  src: '/fonts/dm-sans.woff2',
  fallback: ['system-ui', 'sans-serif'],
});

const mono = font('JetBrains Mono', {
  weight: '100..800',
  src: '/fonts/jb-mono.woff2',
  fallback: ['monospace'],
});

const compiled = compileFonts({ sans, mono });
// compiled.fontFaceCss  — @font-face declarations
// compiled.cssVarsCss   — :root { --font-sans: ...; --font-mono: ...; }
// compiled.cssVarLines  — individual var lines for merging into an existing :root
// compiled.preloadTags  — <link rel="preload" ...> HTML tags

Parameters

ParameterTypeDescription
fontsRecord<string, FontDescriptor>Map of token key to font descriptor. Keys must match [a-zA-Z0-9-].

Returns

CompiledFonts — object with fontFaceCss, cssVarsCss, cssVarLines, and preloadTags.

Types

type CSSInput = Record<string, StyleBlock>;

type CSSOutput<T extends CSSInput> = {
  readonly [K in keyof T & string]: string;
} & { readonly css: string };

type StyleBlock = {
  [property: string]: string | number | StyleBlock;
};

type NestedSelectorBlock = { [selector: string]: CamelCSSDeclarations };
type GlobalStyleBlock = CamelCSSDeclarations | NestedSelectorBlock;
type GlobalCSSInput = Record<string, GlobalStyleBlock>;

interface GlobalCSSOutput {
  css: string;
}

interface VariantsConfig<V extends VariantDefinitions> {
  base: StyleBlock;
  variants: V;
  defaultVariants?: { [K in keyof V]?: keyof V[K] };
  compoundVariants?: CompoundVariant<V>[];
}

interface VariantFunction<V extends VariantDefinitions> {
  (props?: VariantProps<V>): string;
  css: string;
}

type VariantProps<V extends VariantDefinitions> = {
  [K in keyof V]?: keyof V[K];
};

interface FontSrc {
  path: string;
  weight?: string | number;
  style?: 'normal' | 'italic';
}

interface FontOptions {
  weight: string | number;
  style?: 'normal' | 'italic';
  display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
  src?: string | FontSrc[];
  fallback?: string[];
  subsets?: string[];
  unicodeRange?: string;
}

interface FontDescriptor {
  readonly __brand: 'FontDescriptor';
  readonly family: string;
  readonly weight: string;
  readonly style: 'normal' | 'italic';
  readonly display: 'auto' | 'block' | 'swap' | 'fallback' | 'optional';
  readonly src?: string | FontSrc[];
  readonly fallback: string[];
  readonly subsets: string[];
  readonly unicodeRange?: string;
}

interface CompiledFonts {
  fontFaceCss: string;
  cssVarsCss: string;
  cssVarLines: string[];
  preloadTags: string;
}