# Element variations

AsukaDesigner exposes one renderer-neutral variations API. The same call updates linked Fabric views, Babylon products, inactive view snapshots, pricing metadata, history, and physical S/M/L calibration when applicable.

## Apply a variation

Use stable catalog ids. `scope` defaults to `document`, and the complete nested path is resolved automatically:

```ts
const result = await designer.variations.apply({
  elementId: 'demo-product-3d',
  partId: 'handle',
  variationId: 'demo-white-part-handle',
});

if (!result.applied) {
  // The element, part, or variation could not be resolved, or the mutation was denied.
}
```

The result is fully typed:

```ts
{
  applied: true,
  scope: 'document',
  elementId: 'demo-product-3d',
  partId: 'handle',
  variationId: 'demo-white-part-handle',
  variationPathIds: ['demo-part-handle', 'demo-white-part-handle'],
  variationPathNames: ['Handle', 'White'],
  activeViewId: 'preview-3d',
  engine: '3d',
  impactedViewIds: ['front-2d', 'preview-3d'],
}
```

Use `scope: 'object'` with `objectId` when only one runtime instance should change:

```ts
await designer.variations.apply({
  scope: 'object',
  objectId: 'product:runtime-product-id',
  elementId: 'demo-product-3d',
  partId: 'handle',
  variationId: 'demo-blue-part-handle',
});
```

## Inspect the catalog

```ts
const choices = designer.variations.list({
  elementId: 'demo-product-3d',
  partId: 'handle',
});

const active = designer.variations.getActive({
  elementId: 'demo-product-3d',
  partId: 'handle',
});
```

`list()` returns leaf variations with their stable path, part, synchronization key, active state, and optional price.

## Subscribe to changes

```ts
const unsubscribe = designer.variations.subscribe((event) => {
  if (event.type === 'error') console.error(event.error);
});

// Later:
unsubscribe();
```

`designer.api.applyElementVariation(...)` remains available as the lower-level boolean mutation. New integrations should prefer `designer.variations.apply(...)` because it resolves paths and returns structured diagnostics.
