# Contextual parametric controls inside Variations

Product 3D parameters do not need a dedicated layout module. Each element decides whether its parametric recipe is exposed inside the contextual `element-variation-picker` module, and each parameter is assigned to the exact product or part context where it belongs.

## Product definition

```ts
parametric: {
  schemaVersion: 1,
  parameters: [
    { id: 'width', type: 'number', label: 'Width', min: 500, max: 1800, default: 900 },
    { id: 'height', type: 'number', label: 'Height', min: 400, max: 2200, default: 1200 },
    { id: 'handleOffset', type: 'number', label: 'Handle offset', min: -100, max: 100, default: 0 },
  ],
  // parts, computedValues, rules and constraints...
  ui: {
    variationControls: {
      enabled: true,
      placement: 'before',
      scopes: [
        {
          target: 'body',
          title: 'Body dimensions',
          parameterIds: ['width', 'height'],
        },
        {
          target: 'handle',
          title: 'Handle settings',
          parameterIds: ['handleOffset'],
        },
      ],
      compact: true,
    },
  },
}
```

`enabled` is deliberately opt-in. A parametric product without this setting keeps the normal Variations interface.

Each `scopes` entry targets either:

- a Product 3D part id or label such as `body`, `sole`, `front-panel` or `handle`;
- the reserved `@product` target for controls that belong to the element root rather than one concrete part.

A parameter appears only when its matching scope is active. If the customer opens `body`, only the `body` scope is rendered. Returning to the element root hides all part controls unless an explicit `@product` scope exists. No implicit fallback exposes every parameter.

Target matching is resilient to ordinary id/label formatting differences. For example, `front-panel`, `Front panel`, `front_panel` and `frontPanel` resolve to the same contextual key.

## Elements editor

When a Product 3D element contains a parametric recipe, its Variations section displays a **Dimensions in Variations** configuration card. The administrator can:

- enable or disable customer-facing controls;
- place the active scope before or after the current variation list;
- assign parameters separately to the whole product and every detected Product 3D part;
- assign one parameter to multiple contexts when required;
- leave a context empty so no dimensions appear there;
- use the compact presentation intended for inline zones and panels.

Targets are collected from the Product 3D parts, part variation groups and semantic parametric parts. The geometry recipe remains independent from this UI configuration. Disabling or moving controls does not remove parameter values, rules, history or JSON persistence.

## Runtime behavior

The Variations module derives its current scope from the navigation path:

- element list or product root → `@product`;
- selected/clicked part → that part id and aliases;
- nested variation choices → the owning part group remains active.

The controls target the concrete Product 3D instance selected on the canvas. They use the same canonical `parametric3d` runtime API, validation, baseline restoration and history batching as direct API calls.

The demo `index.html` provides four isolated scopes:

- Body → width, height and depth;
- Front panel → panel width and rotation;
- Cap → cap size;
- Handle → offset and visibility.

Selecting one part therefore never displays the parameters of another part.
