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

小工具會以具玻璃擬態風格的橫條呈現，內建淺色與深色主題。你可以從三個層級進行自訂：常用選項的 props、用於主題設定的 CSS 自訂屬性，以及可完整掌控樣式的 CSS 類別覆寫。

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

---

## 主題

`theme` prop 可控制小工具的配色。它會將 `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` 屬性以**內嵌**方式設定。 |
| `--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` 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](/zh-Hant/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>
