> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Personnalisation visuelle

> Personnalisez l’apparence du widget vocal ThunderPhone avec CSS

Le widget s’affiche sous la forme d’une barre au style glassmorphique avec des thèmes clair et sombre intégrés. La personnalisation est disponible à trois niveaux : les props pour les options courantes, les propriétés personnalisées CSS pour les thèmes et les remplacements de classes CSS pour un contrôle total.

<Note>
  Ces options de style s’appliquent au widget préconfiguré rendu par le composant React `ThunderPhoneWidget` et la méthode CDN `ThunderPhone.mount()`. Si vous avez besoin d’une interface utilisateur entièrement personnalisée, utilisez plutôt le [hook headless](/fr/widget/headless-hook).
</Note>

***

## Thèmes

La prop `theme` contrôle le jeu de couleurs du widget. Elle applique une classe `tp--light` ou `tp--dark` à la racine du widget :

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="dark"
/>
```

| Thème     | Classe      | Description                                       |
| --------- | ----------- | ------------------------------------------------- |
| `'light'` | `tp--light` | Arrière-plan clair avec texte sombre. Par défaut. |
| `'dark'`  | `tp--dark`  | Arrière-plan sombre avec texte clair.             |

Les deux thèmes utilisent le design de barre glassmorphique avec un flou d’arrière-plan et une transparence subtile.

***

## Propriétés personnalisées CSS

Le widget expose des propriétés personnalisées CSS (variables) que vous pouvez remplacer pour modifier les couleurs sans toucher aux classes individuelles. Elles sont définies par la classe de thème (`.tp--light` ou `.tp--dark`) appliquée à la racine `.tp-widget` :

| Propriété            | Valeur par défaut (clair)               | Valeur par défaut (sombre)               | Description                                                                                                                                                          |
| -------------------- | --------------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--tp-accent`        | `#000`                                  | `#fff`                                   | Couleur d’accentuation : bouton de démarrage, barres de forme d’onde, point de connexion, texte d’état connecté. Définie **en ligne** depuis la prop `primaryColor`. |
| `--tp-bg`            | `rgba(255, 255, 255, 0.82)`             | `rgba(15, 15, 15, 0.85)`                 | Arrière-plan de la barre (translucide ; flouté par `--tp-glass`).                                                                                                    |
| `--tp-surface`       | `rgba(0, 0, 0, 0.04)`                   | `rgba(255, 255, 255, 0.07)`              | Arrière-plan du bouton de mise en sourdine.                                                                                                                          |
| `--tp-surface-hover` | `rgba(0, 0, 0, 0.07)`                   | `rgba(255, 255, 255, 0.12)`              | Arrière-plan du bouton de mise en sourdine au survol.                                                                                                                |
| `--tp-border`        | `rgba(0, 0, 0, 0.08)`                   | `rgba(255, 255, 255, 0.1)`               | Bordures de la barre et des boutons.                                                                                                                                 |
| `--tp-border-hover`  | `rgba(0, 0, 0, 0.14)`                   | `rgba(255, 255, 255, 0.18)`              | Couleur de bordure au survol.                                                                                                                                        |
| `--tp-text`          | `rgba(0, 0, 0, 0.88)`                   | `rgba(255, 255, 255, 0.95)`              | Texte principal (titre, nom de l’agent).                                                                                                                             |
| `--tp-text-2`        | `rgba(0, 0, 0, 0.5)`                    | `rgba(255, 255, 255, 0.55)`              | Texte secondaire (sous-titre, ligne d’état, minuteur d’appel).                                                                                                       |
| `--tp-glass`         | `blur(32px) saturate(180%)`             | `blur(32px) saturate(180%)`              | `backdrop-filter` qui crée l’effet verre sur la barre.                                                                                                               |
| `--tp-shadow`        | stack d’ombres à trois couches          | stack d’ombres à trois couches           | Le `box-shadow` de la barre (couches anneau + proche + lointaine).                                                                                                   |
| `--tp-shadow-hover`  | stack d’ombres à trois couches          | stack d’ombres à trois couches           | Déclarée pour l’élévation au survol ; actuellement appliquée par aucune règle.                                                                                       |
| `--tp-glow`          | `inset 0 1px 0 0 rgba(255,255,255,0.5)` | `inset 0 1px 0 0 rgba(255,255,255,0.06)` | Mise en évidence supérieure interne superposée à l’ombre de la barre.                                                                                                |
| `--tp-connected`     | `#059669`                               | `#34d399`                                | Couleur de l’indicateur d’état connecté (point d’état).                                                                                                              |
| `--tp-error`         | `#dc2626`                               | `#fb7185`                                | Couleur du texte d’état d’erreur.                                                                                                                                    |
| `--tp-end-bg`        | `rgba(239, 68, 68, 0.08)`               | `rgba(251, 113, 133, 0.12)`              | Arrière-plan du bouton de fin d’appel.                                                                                                                               |
| `--tp-end-color`     | `#ef4444`                               | `#fb7185`                                | Couleur de l’icône du bouton de fin d’appel.                                                                                                                         |
| `--tp-end-border`    | `rgba(239, 68, 68, 0.12)`               | `rgba(251, 113, 133, 0.15)`              | Bordure du bouton de fin d’appel.                                                                                                                                    |
| `--tp-end-hover`     | `rgba(239, 68, 68, 0.14)`               | `rgba(251, 113, 133, 0.2)`               | Arrière-plan du bouton de fin d’appel au survol.                                                                                                                     |
| `--tp-idle-opacity`  | `0.4`                                   | `0.3`                                    | Déclarée pour l’atténuation à l’état inactif ; actuellement appliquée par aucune règle.                                                                              |

### Remplacer des propriétés personnalisées

Définissez la couleur d’accentuation via la prop `primaryColor` :

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#e11d48"
/>
```

<Warning>
  `--tp-accent` est définie comme un **style en ligne** depuis la prop `primaryColor`. Les remplacements de `--tp-accent` dans une feuille de style n’ont donc aucun effet. Modifiez la couleur d’accentuation avec la prop. Toutes les autres propriétés personnalisées peuvent être remplacées en CSS.
</Warning>

Remplacez les autres propriétés personnalisées avec CSS. Utilisez un sélecteur à deux classes (`.tp-widget.tp--light` / `.tp-widget.tp--dark`) afin que votre règle l’emporte sur la classe de thème qui définit les valeurs par défaut, quel que soit l’ordre de la feuille de style :

```css theme={null}
.tp-widget.tp--light {
  --tp-bg: rgba(0, 0, 0, 0.9);
  --tp-text: rgba(255, 255, 255, 0.95);
  --tp-text-2: rgba(255, 255, 255, 0.55);
  --tp-border: rgba(255, 255, 255, 0.15);
}
```

***

## Classes CSS

Toutes les classes du widget sont préfixées par `tp-` afin d’éviter les conflits avec vos styles existants.

| Classe                        | Élément                         | Description                                                                                                                                                                                          |
| ----------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.tp-widget`                  | Wrapper racine                  | Conteneur à position fixe (`position: fixed`, coin défini par la prop `position`, `z-index: 9999`). Contient la classe de thème et les paramètres de police de base ; aucun habillage visuel propre. |
| `.tp--light` / `.tp--dark`    | Modificateurs de thème          | Appliqués à `.tp-widget` avec le thème ; définissent toutes les propriétés personnalisées `--tp-*`.                                                                                                  |
| `.tp-bar`                     | La barre                        | La pilule en verre dépoli elle-même : arrière-plan, flou d’arrière-plan, bordure, rayon de `99px`, ombre. Largeur de `300px`.                                                                        |
| `.tp-meta`                    | Bloc de texte                   | Conteneur pour tout le texte -- titre et sous-titre au repos, nom et statut de l’agent pendant un appel.                                                                                             |
| `.tp-name`                    | Libellé principal               | Affiche la prop `title` au repos, et le nom de l’agent connecté (avec `title` comme valeur de repli) pendant un appel.                                                                               |
| `.tp-sub`                     | Sous-titre                      | La ligne « Disponible maintenant » affichée au repos.                                                                                                                                                |
| `.tp-start`                   | Bouton d’appel au repos         | Le bouton circulaire accentué de démarrage (42px). Utilise `--tp-accent` comme arrière-plan.                                                                                                         |
| `.tp-dot`                     | Point de connexion              | Point accentué pulsant affiché à gauche de la barre pendant la connexion.                                                                                                                            |
| `.tp-wave` / `.tp-wave--idle` | Forme d’onde                    | La forme d’onde à cinq barres. `--idle` ajoute l’animation lente de respiration ; pendant un appel, les barres réagissent à l’audio.                                                                 |
| `.tp-button`                  | Boutons en appel                | Style de base pour les contrôles en appel (42px, arrondi de 12px).                                                                                                                                   |
| `.tp-button-group`            | Ligne de boutons                | Contient les boutons de coupure du micro et de fin pendant un appel.                                                                                                                                 |
| `.tp-button--start`           | Variante du bouton de connexion | Variante de couleur accentuée affichée lorsqu’un appel démarre.                                                                                                                                      |
| `.tp-button--mute`            | Bascule de coupure du micro     | Coupe/rétablit le micro pendant un appel. Utilise `--tp-surface`.                                                                                                                                    |
| `.tp-button--end`             | Bouton de fin d’appel           | Raccroche. Utilise la palette `--tp-end-*`.                                                                                                                                                          |
| `.tp-button--loading`         | Modificateur de chargement      | Atténue le bouton pendant la connexion.                                                                                                                                                              |
| `.tp-icon` / `.tp-spin`       | Icônes                          | Dimensionnement des icônes de bouton ; `tp-spin` anime l’indicateur de connexion.                                                                                                                    |
| `.tp-status`                  | Bloc de statut en appel         | Contient la ligne de statut pendant les états de connexion, connecté ou erreur.                                                                                                                      |
| `.tp-status__text`            | Ligne de statut                 | Texte de l’état de connexion (par exemple, « Connexion... ») ou minuteur d’appel. Reçoit `.tp-status--connected` (couleur accentuée) ou `.tp-status--error` (couleur d’erreur) selon l’état.         |
| `.tp-status__name`            | Emplacement du nom de l’agent   | Fait partie du bloc de statut, mais n’est pas rendu dans la disposition actuelle de la barre -- le nom de l’agent apparaît plutôt dans `.tp-name`.                                                   |
| `.tp-status__dot`             | Point de statut                 | Style de point pulsant pour l’état connecté (utilise `--tp-connected`).                                                                                                                              |

***

## Exemples

### Accent personnalisée via les props

La manière la plus simple de personnaliser l'image de marque du widget :

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="light"
  primaryColor="#059669"
  title="Talk to support"
/>
```

### Couleurs personnalisées via CSS

Remplacez les propriétés personnalisées pour contrôler entièrement les couleurs. N'oubliez pas que l'accent provient de la prop `primaryColor`, et non du CSS :

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#059669"
/>
```

```css theme={null}
/* Emerald theme for everything else */
.tp-widget.tp--light {
  --tp-bg: rgba(236, 253, 245, 0.85);
  --tp-text: rgba(6, 78, 59, 0.95);
  --tp-text-2: rgba(4, 120, 87, 0.8);
  --tp-border: rgba(5, 150, 105, 0.2);
}
```

### Taille personnalisée

Agrandissez ou réduisez le widget en ajustant les dimensions de la barre, des boutons et du texte :

```css theme={null}
/* Wider bar */
.tp-bar {
  width: 340px;
}

/* Larger buttons (42px by default) */
.tp-start,
.tp-button {
  width: 56px;
  height: 56px;
}

/* Larger text */
.tp-name {
  font-size: 16px;
}

.tp-sub,
.tp-status__text {
  font-size: 14px;
}
```

### Masquer les libellés textuels

Tout le texte du widget se trouve dans `.tp-meta`. Masquez-le entièrement pour ne conserver que la forme d'onde et les boutons :

```css theme={null}
.tp-meta {
  display: none;
}
```

Vous pouvez également masquer des éléments individuels :

```css theme={null}
/* Hide only the idle "Available now" subtitle */
.tp-sub {
  display: none;
}

/* Hide only the in-call status line (connection state / timer) */
.tp-status {
  display: none;
}
```

<Note>
  Le libellé inactif se trouve dans `.tp-name`/`.tp-sub`, et non dans `.tp-status` -- masquer uniquement `.tp-status` affiche toujours le titre lorsque le widget est inactif.
</Note>

### Remplacements spécifiques au thème

Ciblez un thème spécifique avec la classe de thème :

```css theme={null}
/* Only affect dark theme */
.tp--dark .tp-start {
  box-shadow: 0 0 20px rgba(255, 255, 255, 0.25);
}

/* Only affect light theme */
.tp-widget.tp--light {
  --tp-bg: rgba(255, 255, 255, 0.95);
}
```

***

## Délimitation avec className

Lorsque vous utilisez le composant React, transmettez une prop `className` pour limiter vos remplacements à une instance spécifique du widget :

```tsx theme={null}
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  theme="dark"
  className="support-widget"
/>
```

Ciblez ensuite cette classe dans votre CSS :

```css theme={null}
.support-widget.tp--dark {
  --tp-bg: rgba(30, 30, 46, 0.9);
}

.support-widget .tp-name {
  font-weight: 700;
}
```

Cela vous permet d'avoir plusieurs instances du widget sur la même page avec des styles différents. Donnez à chaque instance son propre accent via sa prop `primaryColor` (le CSS ne peut pas remplacer `--tp-accent` -- il est défini en ligne).

***

## Interface utilisateur entièrement personnalisée

Si les remplacements CSS ne suffisent pas, le [hook headless](/fr/widget/headless-hook) vous donne un contrôle total. Vous fournissez tout le HTML et le style, tandis que `useThunderPhone` gère la session vocale. Le hook fournit également `audioLevelRef` pour créer des visualisations réactives à l'audio, comme des formes d'onde.

```tsx theme={null}
import { useThunderPhone } from '@thunderphone/widget'

function MyWidget() {
  const phone = useThunderPhone({
    publishableKey: 'pk_live_your_publishable_key',
  })

  return (
    <div className="my-totally-custom-widget">
      {/* Your own buttons, animations, layouts -- anything */}
      <button onClick={phone.state === 'connected' ? phone.disconnect : phone.connect}>
        {phone.state === 'connected' ? 'Hang up' : 'Call us'}
      </button>
      {phone.audio}
    </div>
  )
}
```

<Tip>
  Le hook headless est le bon choix lorsque vous avez besoin d'animations réactives à l'audio, de mises en page personnalisées ou d'une intégration dans une bibliothèque de composants existante. Les remplacements CSS et les propriétés personnalisées sont préférables pour des ajustements rapides de thème.
</Tip>
