# fontFeatureValues

Emit an `@font-feature-values` rule that names OpenType feature indices for a font family.

`fontFeatureValues` gives feature indices readable names for one or more families. Styles then select a named feature through `font-variant-alternates`, such as `styleset(editorial)`.

```ts title="src/fonts.ts"
import { fontFeatureValues } from 'zyzz/web'

fontFeatureValues({
  families: '"Example Font"',
  features: {
    // Emits `@styleset{editorial:1 3;}` inside the rule
    '@styleset': { editorial: [1, 3] },
    '@swash': { decorative: 2 },
  },
})
```

## Signature

```ts
// Families and named feature blocks
fontFeatureValues(options)
```

## Parameters

### options.families

* **Type:** `string | readonly [string, ...string[]]`

A CSS font family list, or a tuple of family names that the compiler quotes individually.

```ts
import { fontFeatureValues } from 'zyzz/web'

fontFeatureValues({
  // Emits `@font-feature-values "Inter","Inter Display"{…}`
  families: ['Inter', 'Inter Display'],
  features: { '@stylistic': { alternate: 1 } },
})
```

### options.features

* **Type:** `fontFeatureValues.Options['features']`

Feature blocks mapping names to indices, in authored order. The blocks are `@annotation`, `@character-variant`, `@ornaments`, `@styleset`, `@stylistic`, and `@swash`. `@styleset` accepts several indices, and `@character-variant` accepts an index with a variation selector.

```ts
import { fontFeatureValues } from 'zyzz/web'

fontFeatureValues({
  families: '"Example Font"',
  features: {
    // Character variant 2, alternate 1
    '@character-variant': { singleStorey: [2, 1] },
  },
})
```

### options.fontDisplay

* **Type:** `'auto' | 'block' | 'fallback' | 'optional' | 'swap'`
* **Default:** `undefined`

The `font-display` descriptor for the family aliases.

```ts
// Emits `font-display:swap;` before the feature blocks
fontFeatureValues({
  families: '"Example Font"',
  features: {},
  fontDisplay: 'swap',
})
```

### options\[atRule]

* **Type:** `` '@layer' | `@${'container' | 'layer' | 'media' | 'supports'}${' ' | '\t' | '\n' | '\r' | '\f' | '(' | `/*${string}*/`}${string}` ``

Grouping keys around a complete definition. Each value holds a complete definition or further grouping keys, and outer keys emit outer groups. A bare `@layer` key emits an anonymous layer.

```ts
import { fontFeatureValues } from 'zyzz/web'

fontFeatureValues({
  // Emits the rule inside `@layer fonts`
  '@layer fonts': {
    families: '"Example Font"',
    features: { '@swash': { decorative: 2 } },
  },
})
```

## Returns

`void`. The compiler erases the call and keeps the rule in the shared stylesheet. Vite, Unplugin, and `zyzz/node` scan the source tree, so unimported modules still contribute. Next.js compiles only imported modules, so import the declaring module from an entrypoint there.

## Types

* **`fontFeatureValues.Options`:** The accepted families, feature blocks, and display policy.

```ts
import type { fontFeatureValues } from 'zyzz/web'

// Reads the accepted feature blocks
type Features = fontFeatureValues.Options['features']
```

## Errors

TypeScript rejects unknown feature blocks and options.

```ts
import { fontFeatureValues } from 'zyzz/web'

// Ligatures are not a feature block
fontFeatureValues({ families: 'Font', features: { '@ligatures': { a: 1 } } })
// error: Argument of type '{ families: string; features: { '@ligatures': { a: number; }; }; }' is not assignable to parameter of type 'never'.
```

The compiler reports `Source.ExtractError` for invalid family lists and indices. Native builds reject the call with `Native.CompileError`.
