# stt/hud — interface HUD web (implémentée)

Front statique **HTML/CSS/JS sans dépendance externe** (tout inline, SVG natifs),
servi localement par le backend (`stt/ui/app.py` — `SimpleHTTPRequestHandler` sur
`ui.http_port`), ouvert en kiosk si `ui.kiosk = true`. Se connecte au serveur
websocket du backend (`ui.ws_port`, défaut **9300**) pour recevoir les états et
renvoyer les réglages.

## Ce qu'affiche le HUD

- **Avatar portrait réactif** (disque) — 3 images crossfadées selon l'état
  (`idle/listening → -idle`, `thinking → -think`, `speaking → -speak`), avec
  anneau fin, « ping » d'écoute et spinner de réflexion. Repli sur l'initiale
  du personnage si aucune image (voir [`avatars/README.md`](avatars/README.md)).
- **Label d'état** : veille / écoute / réflexion / réponse.
- **Transcript** : bulles utilisateur / assistant (+ tag du modèle) / erreur.
- **Composer texte** (sous le transcript) : champ + bouton « Envoyer » pour
  dialoguer **au clavier** sans micro — Entrée envoie, Maj+Entrée saute une ligne.
  Le texte passe par le même cerveau que le vocal (modèle local / avancé).
- **Indicateur de connexion** websocket (point + libellé), reconnexion auto.
- **Drawer Réglages** (engrenage) : intensité de l'accent (thème), avatar, voix,
  mot de réveil, mode cerveau (local/avancé), no-think, reset conversation.

## Protocole websocket

Reçus du backend (diffusés à tous les HUD connectés) :

| Événement | Effet |
|---|---|
| `{"type":"state","state":"idle\|listening\|thinking\|speaking"}` | animation + label |
| `{"type":"user","text":…}` | bulle utilisateur |
| `{"type":"assistant","text":…,"mode":…}` | bulle assistant (+ tag modèle) |
| `{"type":"error","text":…}` | bulle d'erreur |

Envoyés au backend :

```json
{"type":"settings","data":{"brainMode":"local","wakeword":"…","action":"reset"}}
{"type":"text","text":"quelle heure est-il ?"}
```

Le serveur applique `action:reset`, `brainMode` (→ modèle LiteLLM) et `wakeword`
**à chaud** (`_apply_settings` dans `stt/ui/app.py`). Un message `text` est traité
comme un tour de conversation (`VoiceEngine.respond_text`, hors boucle audio) : le
backend renvoie alors les événements `user` puis `assistant` — le HUD n'ajoute donc
pas la bulle utilisateur lui-même quand il est connecté. Les réglages purement
visuels (intensité d'accent, avatar) sont persistés côté navigateur (localStorage).

## Prévisualiser sans backend

Le HUD embarque un **mode démo** : passer `const DEMO = false` à `true` en tête
du `<script>` rejoue une boucle d'événements simulés — pratique pour itérer le
design sans lancer le serveur. Défaut livré : `false` (branché sur le backend).

## Design & personnalisation

Esthétique douce (blanc + accent rose → rouge), origine **Claude Design**. Les
variables CSS en tête du `<style>` pilotent le rendu (`--accent-rest`,
`--accent-active`, `--avatar`, `--ring-gap`…) ; le slider « intensité » interpole
l'accent au repos. Portraits dans [`avatars/`](avatars/) (jeux `asa` / `mira` /
`kai`, swappables à chaud depuis les Réglages).
