> ## 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.

# Estilos

> Personaliza la apariencia del widget de voz de ThunderPhone con CSS

El widget se muestra como una barra con efecto vidrio, con temas claro y oscuro integrados. La personalización está disponible en tres niveles: props para opciones comunes, propiedades personalizadas de CSS para los temas y anulaciones de clases CSS para un control total.

<Note>
  Estas opciones de estilo se aplican al widget prediseñado que renderizan el componente React `ThunderPhoneWidget` y el método CDN `ThunderPhone.mount()`. Si necesitas una interfaz completamente personalizada, usa el [hook headless](/es/widget/headless-hook).
</Note>

***

## Temas

La prop `theme` controla el esquema de colores del widget. Aplica una clase `tp--light` o `tp--dark` a la raíz del widget:

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

| Tema      | Clase       | Descripción                                   |
| --------- | ----------- | --------------------------------------------- |
| `'light'` | `tp--light` | Fondo claro con texto oscuro. Predeterminado. |
| `'dark'`  | `tp--dark`  | Fondo oscuro con texto claro.                 |

Ambos temas usan el diseño de barra con efecto vidrio, desenfoque de fondo y transparencia sutil.

***

## Propiedades personalizadas de CSS

El widget expone propiedades personalizadas de CSS (variables) que puedes sobrescribir para cambiar colores sin modificar clases individuales. Se definen mediante la clase de tema (`.tp--light` o `.tp--dark`) aplicada a la raíz `.tp-widget`:

| Propiedad            | Predeterminado (claro)                  | Predeterminado (oscuro)                  | Descripción                                                                                                                                                       |
| -------------------- | --------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--tp-accent`        | `#000`                                  | `#fff`                                   | Color de acento: botón de inicio, barras de forma de onda, punto de conexión y texto de estado conectado. Se establece **en línea** desde la prop `primaryColor`. |
| `--tp-bg`            | `rgba(255, 255, 255, 0.82)`             | `rgba(15, 15, 15, 0.85)`                 | Fondo de la barra (translúcido; difuminado por `--tp-glass`).                                                                                                     |
| `--tp-surface`       | `rgba(0, 0, 0, 0.04)`                   | `rgba(255, 255, 255, 0.07)`              | Fondo del botón de silenciar.                                                                                                                                     |
| `--tp-surface-hover` | `rgba(0, 0, 0, 0.07)`                   | `rgba(255, 255, 255, 0.12)`              | Fondo del botón de silenciar al pasar el cursor.                                                                                                                  |
| `--tp-border`        | `rgba(0, 0, 0, 0.08)`                   | `rgba(255, 255, 255, 0.1)`               | Bordes de la barra y los botones.                                                                                                                                 |
| `--tp-border-hover`  | `rgba(0, 0, 0, 0.14)`                   | `rgba(255, 255, 255, 0.18)`              | Color del borde al pasar el cursor.                                                                                                                               |
| `--tp-text`          | `rgba(0, 0, 0, 0.88)`                   | `rgba(255, 255, 255, 0.95)`              | Texto principal (título, nombre del agente).                                                                                                                      |
| `--tp-text-2`        | `rgba(0, 0, 0, 0.5)`                    | `rgba(255, 255, 255, 0.55)`              | Texto secundario (subtítulo, línea de estado, temporizador de llamada).                                                                                           |
| `--tp-glass`         | `blur(32px) saturate(180%)`             | `blur(32px) saturate(180%)`              | `backdrop-filter` que crea el efecto de vidrio en la barra.                                                                                                       |
| `--tp-shadow`        | sombra de tres capas                    | sombra de tres capas                     | El `box-shadow` de la barra (capas de anillo + cercana + lejana).                                                                                                 |
| `--tp-shadow-hover`  | sombra de tres capas                    | sombra de tres capas                     | Declarada para la elevación al pasar el cursor; actualmente no la aplica ninguna regla.                                                                           |
| `--tp-glow`          | `inset 0 1px 0 0 rgba(255,255,255,0.5)` | `inset 0 1px 0 0 rgba(255,255,255,0.06)` | Resalte superior interno superpuesto a la sombra de la barra.                                                                                                     |
| `--tp-connected`     | `#059669`                               | `#34d399`                                | Color del indicador de estado conectado (punto de estado).                                                                                                        |
| `--tp-error`         | `#dc2626`                               | `#fb7185`                                | Color del texto de estado de error.                                                                                                                               |
| `--tp-end-bg`        | `rgba(239, 68, 68, 0.08)`               | `rgba(251, 113, 133, 0.12)`              | Fondo del botón para finalizar llamada.                                                                                                                           |
| `--tp-end-color`     | `#ef4444`                               | `#fb7185`                                | Color del ícono del botón para finalizar llamada.                                                                                                                 |
| `--tp-end-border`    | `rgba(239, 68, 68, 0.12)`               | `rgba(251, 113, 133, 0.15)`              | Borde del botón para finalizar llamada.                                                                                                                           |
| `--tp-end-hover`     | `rgba(239, 68, 68, 0.14)`               | `rgba(251, 113, 133, 0.2)`               | Fondo del botón para finalizar llamada al pasar el cursor.                                                                                                        |
| `--tp-idle-opacity`  | `0.4`                                   | `0.3`                                    | Declarada para atenuar el estado inactivo; actualmente no la aplica ninguna regla.                                                                                |

### Sobrescribir propiedades personalizadas

Establece el color de acento mediante la prop `primaryColor`:

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

<Warning>
  `--tp-accent` se establece como un **estilo en línea** desde la prop `primaryColor`, por lo que las sobrescrituras de `--tp-accent` en la hoja de estilos no tienen efecto. Cambia el acento con la prop. Todas las demás propiedades personalizadas se pueden sobrescribir en CSS.
</Warning>

Sobrescribe las demás propiedades personalizadas con CSS. Usa un selector de dos clases (`.tp-widget.tp--light` / `.tp-widget.tp--dark`) para que tu regla tenga prioridad sobre la clase de tema que define los valores predeterminados, independientemente del orden de las hojas de estilos:

```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);
}
```

***

## Clases de CSS

Todas las clases del widget tienen el prefijo `tp-` para evitar conflictos con tus estilos existentes.

| Clase                         | Elemento                            | Descripción                                                                                                                                                                                                 |
| ----------------------------- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.tp-widget`                  | Contenedor raíz                     | Contenedor de posición fija (`position: fixed`, esquina definida por la prop `position`, `z-index: 9999`). Incluye la clase de tema y la configuración base de fuente; no tiene elementos visuales propios. |
| `.tp--light` / `.tp--dark`    | Modificadores de tema               | Se aplican a `.tp-widget` junto con el tema; definen todas las propiedades personalizadas `--tp-*`.                                                                                                         |
| `.tp-bar`                     | La barra                            | La píldora con efecto de vidrio: fondo, desenfoque de fondo, borde, radio de `99px`, sombra. Ancho de `300px`.                                                                                              |
| `.tp-meta`                    | Bloque de texto                     | Contenedor para todo el texto: título y subtítulo en espera, nombre y estado del agente durante una llamada.                                                                                                |
| `.tp-name`                    | Etiqueta principal                  | Muestra la prop `title` en espera y el nombre del agente conectado (usa `title` como alternativa) durante una llamada.                                                                                      |
| `.tp-sub`                     | Subtítulo                           | La línea "Disponible ahora" que se muestra en espera.                                                                                                                                                       |
| `.tp-start`                   | Botón de llamada en espera          | El botón circular de inicio con color de acento (42px). Usa `--tp-accent` como fondo.                                                                                                                       |
| `.tp-dot`                     | Punto de conexión                   | Punto de acento pulsante que se muestra a la izquierda de la barra mientras se conecta.                                                                                                                     |
| `.tp-wave` / `.tp-wave--idle` | Forma de onda                       | La forma de onda de cinco barras. `--idle` agrega la animación lenta de respiración; durante una llamada, las barras reaccionan al audio.                                                                   |
| `.tp-button`                  | Botones durante la llamada          | Estilo base para los controles durante la llamada (42px, esquinas redondeadas de 12px).                                                                                                                     |
| `.tp-button-group`            | Fila de botones                     | Agrupa los botones de silenciar y finalizar durante una llamada.                                                                                                                                            |
| `.tp-button--start`           | Variante de botón de conexión       | Variante con color de acento que se muestra mientras se inicia una llamada.                                                                                                                                 |
| `.tp-button--mute`            | Alternador de silenciar             | Silencia o activa el micrófono durante una llamada. Usa `--tp-surface`.                                                                                                                                     |
| `.tp-button--end`             | Botón para finalizar llamada        | Cuelga la llamada. Usa la paleta `--tp-end-*`.                                                                                                                                                              |
| `.tp-button--loading`         | Modificador de carga                | Atenúa el botón mientras se conecta.                                                                                                                                                                        |
| `.tp-icon` / `.tp-spin`       | Iconos                              | Tamaño de iconos de botones; `tp-spin` anima el indicador giratorio de conexión.                                                                                                                            |
| `.tp-status`                  | Bloque de estado durante la llamada | Agrupa la línea de estado durante los estados de conexión, conectado o error.                                                                                                                               |
| `.tp-status__text`            | Línea de estado                     | Texto del estado de conexión (por ejemplo, "Conectando...") o el temporizador de llamada. Recibe `.tp-status--connected` (color de acento) o `.tp-status--error` (color de error) según el estado.          |
| `.tp-status__name`            | Espacio para el nombre del agente   | Forma parte del bloque de estado, pero no se renderiza en el diseño actual de la barra: el nombre del agente aparece en `.tp-name`.                                                                         |
| `.tp-status__dot`             | Punto de estado                     | Estilo de punto pulsante para el estado conectado (usa `--tp-connected`).                                                                                                                                   |

***

## Ejemplos

### Color de acento personalizado mediante props

La forma más sencilla de aplicar tu marca al widget:

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

### Colores personalizados mediante CSS

Sobrescribe las propiedades personalizadas para tener control total sobre los colores. Recuerda que el acento proviene de la prop `primaryColor`, no de 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);
}
```

### Tamaño personalizado

Haz que el widget sea más grande o más pequeño ajustando las dimensiones de la barra, los botones y el texto:

```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;
}
```

### Ocultar las etiquetas de texto

Todo el texto del widget está en `.tp-meta`. Ocúltalo por completo para conservar solo la forma de onda y los botones:

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

O bien, oculta elementos individuales:

```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>
  La etiqueta inactiva está en `.tp-name`/`.tp-sub`, no en `.tp-status` -- ocultar solo `.tp-status` sigue mostrando el título cuando el widget está inactivo.
</Note>

### Sobrescrituras específicas del tema

Aplica estilos a un tema específico mediante la clase del tema:

```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);
}
```

***

## Alcance con className

Al usar el componente React, pasa una prop `className` para limitar tus sobrescrituras a una instancia específica del widget:

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

Luego aplica estilos a esa clase en tu CSS:

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

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

Esto te permite tener varias instancias del widget en la misma página con estilos distintos. Asigna a cada instancia su propio acento mediante su prop `primaryColor` (CSS no puede sobrescribir `--tp-accent` -- se establece en línea).

***

## Interfaz de usuario totalmente personalizada

Si las sobrescrituras de CSS no son suficientes, el [hook sin interfaz](/es/widget/headless-hook) te brinda control total. Tú proporcionas todo el HTML y los estilos, mientras que `useThunderPhone` gestiona la sesión de voz. El hook también proporciona `audioLevelRef` para crear visualizaciones reactivas al audio, como formas de onda.

```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>
  El hook sin interfaz es la opción adecuada cuando necesitas animaciones reactivas al audio, diseños personalizados o integración con una biblioteca de componentes existente. Las sobrescrituras de CSS y las propiedades personalizadas son mejores para ajustes rápidos de temas.
</Tip>
