# @circuy/sdk

Moteur d'exécution des parcours sur le site hôte. Il charge un JSON, résout les cibles, affiche les étapes dans un Shadow DOM, et dégrade en silence en cas d'échec.

Pas de backend requis : le lot 1 fonctionne avec un fichier JSON local.

## Intégration

```html
<script src="https://cdn.circuy.net/v1/sdk.js" data-key="pk_live_…" data-tours="https://cdn.circuy.net/v1/p/pk_live_…/manifest.json" async></script>
```

En local, la démo utilise `data-tours` :

```html
<script src="/sdk/sdk.global.js" data-key="pk_demo" data-tours="/tours.json" async></script>
```

API globale, y compris avant le chargement du script :

```js
circuy("identify", { role: "admin", locale: "fr" });
circuy("start", "tr_onboarding");
```

## Contenu actuel

- Résolution de cible et attente `MutationObserver` (5 s)
- Rendu `@floating-ui/dom` dans un Shadow Root ouvert
- Persistance `localStorage` (TTL 24 h, clé `seen`)
- Branchements, clavier (Échap), piège de focus sur modale/question
- Télémétrie en mémoire (envoi Beacon dès qu'une URL d'événements existe)
- Mode `preview` du moteur : pas de persistance ni de télémétrie (prévisualisation dans l'extension)

Budget gzip : 40 Ko, alerte à 35 Ko. Mesure : `node scripts/check-sdk-size.mjs`.

## Commandes

```bash
pnpm --filter @circuy/sdk build
pnpm --filter @circuy/sdk demo      # http://127.0.0.1:4173
pnpm --filter @circuy/sdk test:e2e
```

Banc de résilience : `bench/gen-1.html` … `gen-3.html`. Seuil bloquant : 100 % de survie en génération 2.
