---
title: "Стилизация"
description: "Персонализирайте външния вид на гласовия уиджет ThunderPhone с CSS"
---

Уиджетът се визуализира като стъкломорфна лента с вградени светла и тъмна тема. Персонализирането е достъпно на три нива: props за често срещани опции, персонализирани CSS свойства за теми и заместване на CSS класове за пълен контрол.

<Note>
  Тези опции за стилизиране се прилагат за предварително създадения уиджет, визуализиран от React компонента `ThunderPhoneWidget` и CDN метода `ThunderPhone.mount()`. Ако имате нужда от изцяло персонализиран интерфейс, използвайте вместо това [headless hook](/bg/widget/headless-hook).
</Note>

---

## Теми

Prop-ът `theme` управлява цветовата схема на уиджета. Той прилага клас `tp--light` или `tp--dark` към корена на уиджета:

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

| Тема | Клас | Описание |
|-------|-------|-------------|
| `'light'` | `tp--light` | Светъл фон с тъмен текст. По подразбиране. |
| `'dark'` | `tp--dark` | Тъмен фон със светъл текст. |

И двете теми използват дизайн на стъкломорфна лента със замъгляване на фона и деликатна прозрачност.

---

## Персонализирани CSS свойства

Уиджетът предоставя персонализирани CSS свойства (променливи), които можете да презапишете, за да промените цветовете, без да променяте отделни класове. Те се дефинират от класа на темата (`.tp--light` или `.tp--dark`), приложен към корена `.tp-widget`:

| Свойство | По подразбиране (светла) | По подразбиране (тъмна) | Описание |
|----------|-----------------|-----------------|-------------|
| `--tp-accent` | `#000` | `#fff` | Акцентен цвят: бутон за стартиране, ленти на звуковата вълна, точка за свързване, текст за състояние на свързване. Задава се **инлайн** чрез пропа `primaryColor`. |
| `--tp-bg` | `rgba(255, 255, 255, 0.82)` | `rgba(15, 15, 15, 0.85)` | Фон на лентата (полупрозрачен; замъглява се от `--tp-glass`). |
| `--tp-surface` | `rgba(0, 0, 0, 0.04)` | `rgba(255, 255, 255, 0.07)` | Фон на бутона за заглушаване. |
| `--tp-surface-hover` | `rgba(0, 0, 0, 0.07)` | `rgba(255, 255, 255, 0.12)` | Фон на бутона за заглушаване при посочване. |
| `--tp-border` | `rgba(0, 0, 0, 0.08)` | `rgba(255, 255, 255, 0.1)` | Контури на лентата и бутоните. |
| `--tp-border-hover` | `rgba(0, 0, 0, 0.14)` | `rgba(255, 255, 255, 0.18)` | Цвят на контура при посочване. |
| `--tp-text` | `rgba(0, 0, 0, 0.88)` | `rgba(255, 255, 255, 0.95)` | Основен текст (заглавие, име на агента). |
| `--tp-text-2` | `rgba(0, 0, 0, 0.5)` | `rgba(255, 255, 255, 0.55)` | Вторичен текст (подзаглавие, ред за състояние, таймер на разговора). |
| `--tp-glass` | `blur(32px) saturate(180%)` | `blur(32px) saturate(180%)` | `backdrop-filter`, който създава стъкления ефект върху лентата. |
| `--tp-shadow` | стек от сенки с три слоя | стек от сенки с три слоя | `box-shadow` на лентата (пръстен + близък + далечен слой). |
| `--tp-shadow-hover` | стек от сенки с три слоя | стек от сенки с три слоя | Декларирано за повдигане при посочване; понастоящем не се прилага от никое правило. |
| `--tp-glow` | `inset 0 1px 0 0 rgba(255,255,255,0.5)` | `inset 0 1px 0 0 rgba(255,255,255,0.06)` | Вътрешен горен акцент, добавен като слой към сянката на лентата. |
| `--tp-connected` | `#059669` | `#34d399` | Цвят на индикатора за състояние на свързване (точка за състояние). |
| `--tp-error` | `#dc2626` | `#fb7185` | Цвят на текста за състояние при грешка. |
| `--tp-end-bg` | `rgba(239, 68, 68, 0.08)` | `rgba(251, 113, 133, 0.12)` | Фон на бутона за прекратяване на разговора. |
| `--tp-end-color` | `#ef4444` | `#fb7185` | Цвят на иконата на бутона за прекратяване на разговора. |
| `--tp-end-border` | `rgba(239, 68, 68, 0.12)` | `rgba(251, 113, 133, 0.15)` | Контур на бутона за прекратяване на разговора. |
| `--tp-end-hover` | `rgba(239, 68, 68, 0.14)` | `rgba(251, 113, 133, 0.2)` | Фон на бутона за прекратяване на разговора при посочване. |
| `--tp-idle-opacity` | `0.4` | `0.3` | Декларирано за затъмняване в неактивно състояние; понастоящем не се прилага от никое правило. |

### Презаписване на персонализирани свойства

Задайте акцентния цвят чрез пропа `primaryColor`:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#e11d48"
/>
```

<Warning>
  `--tp-accent` се задава като **инлайн стил** чрез пропа `primaryColor`, затова презаписванията на `--tp-accent` в стиловата таблица нямат ефект. Променете акцентния цвят чрез пропа. Всички останали персонализирани свойства могат да бъдат презаписани в CSS.
</Warning>

Презапишете останалите персонализирани свойства с CSS. Използвайте селектор с два класа (`.tp-widget.tp--light` / `.tp-widget.tp--dark`), така че вашето правило да има предимство пред класа на темата, който дефинира стойностите по подразбиране, независимо от реда в стиловата таблица:

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

---

## CSS класове

Всички класове на уиджета са с префикс `tp-`, за да се избегнат конфликти със съществуващите ви стилове.

| Клас | Елемент | Описание |
|-------|---------|-------------|
| `.tp-widget` | Основна обвивка | Контейнер с фиксирана позиция (`position: fixed`, ъгълът се задава от пропа `position`, `z-index: 9999`). Съдържа класа за темата и основните настройки за шрифта; няма собствена визуална рамка. |
| `.tp--light` / `.tp--dark` | Модификатори на темата | Прилагат се към `.tp-widget` заедно с темата; дефинират всички персонализирани свойства `--tp-*`. |
| `.tp-bar` | Лента | Самата стъклоподобна капсула: фон, размазване на фона, рамка, радиус `99px`, сянка. Ширина `300px`. |
| `.tp-meta` | Текстов блок | Контейнер за целия текст — заглавие и подзаглавие в неактивно състояние, име и статус на агента по време на разговор. |
| `.tp-name` | Основен етикет | Показва пропа `title` в неактивно състояние и името на свързания агент (като използва `title` при липса на име) по време на разговор. |
| `.tp-sub` | Подзаглавие | Редът „Налично сега“, показван в неактивно състояние. |
| `.tp-start` | Бутон за обаждане в неактивно състояние | Кръглият акцентен бутон за стартиране (42px). Използва `--tp-accent` за фон. |
| `.tp-dot` | Точка за свързване | Пулсираща акцентна точка, показвана вляво от лентата при свързване. |
| `.tp-wave` / `.tp-wave--idle` | Вълнова форма | Вълновата форма с пет ленти. `--idle` добавя бавна анимация на пулсиране; по време на разговор лентите реагират на аудиото. |
| `.tp-button` | Бутони по време на разговор | Базов стил за контролите по време на разговор (42px, заобляне 12px). |
| `.tp-button-group` | Ред с бутони | Обвива бутоните за заглушаване и прекратяване по време на разговор. |
| `.tp-button--start` | Вариант на бутона за свързване | Вариант с акцентен цвят, показван при стартиране на разговор. |
| `.tp-button--mute` | Превключвател за заглушаване | Заглушава/включва микрофона по време на разговор. Използва `--tp-surface`. |
| `.tp-button--end` | Бутон за прекратяване на разговор | Прекратява разговора. Използва палитрата `--tp-end-*`. |
| `.tp-button--loading` | Модификатор за зареждане | Затъмнява бутона при свързване. |
| `.tp-icon` / `.tp-spin` | Икони | Размер на иконите на бутоните; `tp-spin` анимира индикатора за свързване. |
| `.tp-status` | Блок за статус по време на разговор | Обвива реда за статус при състояния на свързване/свързан/грешка. |
| `.tp-status__text` | Ред за статус | Текст за състоянието на връзката (например „Свързване...“) или таймерът на разговора. Получава `.tp-status--connected` (акцентен цвят) или `.tp-status--error` (цвят за грешка) според състоянието. |
| `.tp-status__name` | Поле за име на агент | Част от блока за статус, но не се визуализира в текущото оформление на лентата — името на агента се показва в `.tp-name`. |
| `.tp-status__dot` | Точка за статус | Стил за пулсираща точка при свързано състояние (използва `--tp-connected`). |

---

## Примери

### Персонализиран акцент чрез пропсове

Най-лесният начин да брандирате уиджета:

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

### Персонализирани цветове чрез CSS

Заменете персонализираните свойства за пълен контрол върху цветовете. Имайте предвид, че акцентът идва от пропса `primaryColor`, а не от CSS:

```tsx
<ThunderPhoneWidget
  publishableKey="pk_live_your_publishable_key"
  primaryColor="#059669"
/>
```

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

### Персонализиран размер

Направете уиджета по-голям или по-малък, като коригирате размерите на лентата, бутоните и текста:

```css
/* 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;
}
```

### Скриване на текстовите етикети

Целият текст на уиджета се намира в `.tp-meta`. Скрийте го изцяло, за да запазите само формата на вълната и бутоните:

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

Или скрийте отделни части:

```css
/* 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>
  Етикетът в неактивно състояние се намира в `.tp-name`/`.tp-sub`, а не в `.tp-status` -- скриването само на `.tp-status` все още показва заглавието, когато уиджетът е неактивен.
</Note>

### Замени за конкретна тема

Насочете се към конкретна тема чрез класа на темата:

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

---

## Обхват чрез className

Когато използвате React компонента, подайте пропс `className`, за да ограничите замените си до конкретен екземпляр на уиджета:

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

След това насочете този клас във вашия CSS:

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

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

Това ви позволява да имате няколко екземпляра на уиджета на една и съща страница с различни стилове. Задайте на всеки екземпляр собствен акцент чрез неговия пропс `primaryColor` (CSS не може да замени `--tp-accent` -- той се задава вградeно).

---

## Напълно персонализиран интерфейс

Ако CSS замените не са достатъчни, [headless hook](/bg/widget/headless-hook) ви дава пълен контрол. Вие предоставяте целия HTML и стилизиране, докато `useThunderPhone` управлява гласовата сесия. Hook-ът предоставя и `audioLevelRef` за изграждане на аудиореактивни визуализации, като форми на вълната.

```tsx
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>
  Headless hook-ът е правилният избор, когато имате нужда от аудиореактивни анимации, персонализирани оформления или интеграция в съществуваща библиотека с компоненти. CSS замените и персонализираните свойства са по-подходящи за бързи корекции на темата.
</Tip>
