> ## 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.

# CSS

> API reference for css(), variants(), globalCss(), font(), and compileFonts()

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.

```tsx theme={null}
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

```ts theme={null}
function css<T extends CSSInput>(input: T, filePath?: string): CSSOutput<T>;
```

### Parameters

| Parameter  | Type       | Description                                        |
| ---------- | ---------- | -------------------------------------------------- |
| `input`    | `CSSInput` | Object mapping block names to `StyleBlock` objects |
| `filePath` | `string`   | Used 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:

```tsx theme={null}
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.

```tsx theme={null}
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:

```tsx theme={null}
// ❌ 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.

```tsx theme={null}
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

```ts theme={null}
function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;
```

### VariantsConfig

| Property           | Type                   | Description                                                  |
| ------------------ | ---------------------- | ------------------------------------------------------------ |
| `base`             | `StyleBlock`           | Base styles applied to all variants                          |
| `variants`         | `V`                    | Object mapping variant names to option → `StyleBlock` maps   |
| `defaultVariants`  | `Partial<V>`           | Default variant selections when not specified                |
| `compoundVariants` | `CompoundVariant<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

```tsx theme={null}
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.

```ts theme={null}
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.

```ts theme={null}
globalCss({
  '@keyframes spin': {
    from: { transform: 'rotate(0deg)' },
    to: { transform: 'rotate(360deg)' },
  },
  '@media (min-width: 768px)': {
    body: { fontSize: '18px' },
  },
});
```

### Signature

```ts theme={null}
function globalCss(input: GlobalCSSInput): GlobalCSSOutput;
```

### Parameters

| Parameter | Type             | Description                                                                                              |
| --------- | ---------------- | -------------------------------------------------------------------------------------------------------- |
| `input`   | `GlobalCSSInput` | Selector → 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.

```tsx theme={null}
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

| Parameter | Type          | Description                              |
| --------- | ------------- | ---------------------------------------- |
| `family`  | `string`      | The font family name (e.g., `'DM Sans'`) |
| `options` | `FontOptions` | Font 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.

```tsx theme={null}
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

| Parameter | Type                             | Description                                                          |
| --------- | -------------------------------- | -------------------------------------------------------------------- |
| `fonts`   | `Record<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

```ts theme={null}
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;
}
```
