---
title: "樣式設定"
description: "使用 CSS 自訂 ThunderPhone 語音小工具的外觀"
---

小工具會呈現為配備內建淺色及深色主題的玻璃擬態橫條。你可從三個層級自訂：適用於常用選項的屬性、用於主題設定的 CSS 自訂屬性，以及可提供完整控制權的 CSS 類別覆寫。

<Note>
  以下樣式選項適用於由 `ThunderPhoneWidget` React 元件及 `ThunderPhone.mount()` CDN 方法呈現的預建小工具。如需完全自訂的 UI，請改用 [無介面 hook](/yue/widget/headless-hook)。
</Note>

---

## 主題

`theme` 屬性可控制小工具的配色方案。它會將 `tp--light` 或 `tp--dark` 類別套用至小工具根元素：

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

| 主題 | 類別 | 說明 |
|-------|-------|-------------|
| `'light'` | `tp--light` | 淺色背景配深色文字。預設值。 |
| `'dark'` | `tp--dark` | 深色背景配淺色文字。 |

兩種主題均採用具備背景模糊效果及細緻透明度的玻璃擬態橫條設計。

---

## CSS 自訂屬性

此小工具提供可覆寫的 CSS 自訂屬性（變數），讓你毋須修改個別類別即可變更顏色。這些屬性由套用至 `.tp-widget` 根元素的主題類別（`.tp--light` 或 `.tp--dark`）定義：

| 屬性 | 預設值（淺色） | 預設值（深色） | 說明 |
|----------|-----------------|-----------------|-------------|
| `--tp-accent` | `#000` | `#fff` | 強調色：開始按鈕、波形條、連線圓點、已連線狀態文字。透過 `primaryColor` prop **行內**設定。 |
| `--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` prop 設定強調色：

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

<Warning>
  `--tp-accent` 會透過 `primaryColor` prop 設定為**行內樣式**，因此在樣式表中覆寫 `--tp-accent` 不會生效。請使用 prop 變更強調色。所有其他自訂屬性均可在 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` prop 設定，`z-index: 9999`）。包含主題類別及基本字型設定；本身沒有視覺外框。 |
| `.tp--light` / `.tp--dark` | 主題修飾類別 | 與主題一同套用至 `.tp-widget`；定義所有 `--tp-*` 自訂屬性。 |
| `.tp-bar` | 工具列 | 玻璃擬態膠囊式工具列本體：背景、背景模糊、邊框、`99px` 圓角半徑及陰影。寬度為 `300px`。 |
| `.tp-meta` | 文字區塊 | 包含所有文字的容器——閒置時顯示標題及副標題，通話期間顯示智能體名稱及狀態。 |
| `.tp-name` | 主要標籤 | 閒置時顯示 `title` prop；通話期間顯示已連線智能體的名稱（如未設定則使用 `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`）。 |

---

## 範例

### 透過 Props 自訂強調色

為小工具加入品牌風格的最簡單方法：

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

### 透過 CSS 自訂顏色

覆寫自訂屬性，以全面控制顏色。請記住，強調色來自 `primaryColor` prop，而非 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>

### 特定主題覆寫

使用主題 class 針對特定主題：

```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` prop，將覆寫設定套用至特定小工具實例：

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

然後在 CSS 中針對該 class 設定樣式：

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

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

這讓你可在同一頁面使用多個不同樣式的小工具實例。透過各實例的 `primaryColor` prop 設定專屬強調色（CSS 無法覆寫 `--tp-accent`——此屬性以 inline 方式設定）。

---

## 完全自訂 UI

如果 CSS 覆寫不足夠，[無介面 hook](/yue/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>
  當你需要因應音訊變化的動畫、自訂版面配置，或整合至現有元件庫時，無介面 hook 是合適選擇。CSS 覆寫及自訂屬性則更適合快速調整主題風格。
</Tip>
