---
title: "スタイリング"
description: "CSS で ThunderPhone 音声ウィジェットの外観をカスタマイズ"
---

ウィジェットは、ライトテーマとダークテーマを内蔵したグラスモーフィズムのバーとして表示されます。カスタマイズは3つのレベルで可能です。一般的なオプション用のprops、テーマ設定用のCSSカスタムプロパティ、完全な制御を行うためのCSSクラスオーバーライドを使用できます。

<Note>
  これらのスタイリングオプションは、`ThunderPhoneWidget` Reactコンポーネントおよび`ThunderPhone.mount()` CDNメソッドで表示されるビルド済みウィジェットに適用されます。完全にカスタムなUIが必要な場合は、代わりに[ヘッドレスフック](/ja/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` | 3層のシャドウスタック | 3層のシャドウスタック | バーの `box-shadow`（リング + 近距離 + 遠距離レイヤー）。 |
| `--tp-shadow-hover` | 3層のシャドウスタック | 3層のシャドウスタック | ホバー時の浮き上がり用に宣言されていますが、現在はいずれのルールにも適用されていません。 |
| `--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 でオーバーライドします。スタイルシートの順序にかかわらず、デフォルトを定義するテーマクラスよりルールの優先度を高くするため、2クラスセレクター（`.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` | サブタイトル | 待機中に表示される「Available now」の行です。 |
| `.tp-start` | 待機中の通話ボタン | 円形のアクセント付き開始ボタン（42px）。背景に `--tp-accent` を使用します。 |
| `.tp-dot` | 接続ドット | 接続中にバーの左側に表示される、パルスするアクセントドットです。 |
| `.tp-wave` / `.tp-wave--idle` | 波形 | 5本バーの波形です。`--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` | ステータス行 | 接続状態のテキスト（例: 「Connecting...」）または通話タイマーです。状態に応じて `.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 によるカスタムカラー

カスタムプロパティを上書きして、カラーを完全に制御します。アクセントは CSS ではなく `primaryColor` props から設定される点に注意してください:

```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-status` ではなく `.tp-name`/`.tp-sub` にあります。`.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` props を渡して、上書きを特定のウィジェットインスタンスに限定します:

```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` props を使用して、それぞれに独自のアクセントを設定します（`--tp-accent` はインラインで設定されるため、CSS では上書きできません）。

---

## 完全にカスタムな UI

CSS の上書きだけでは不十分な場合、[ヘッドレスフック](/ja/widget/headless-hook) を使用すると完全に制御できます。すべての HTML とスタイリングを用意し、`useThunderPhone` が音声セッションを処理します。このフックは、波形のようなオーディオ反応型ビジュアライゼーションを構築するための `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>
  オーディオ反応型アニメーション、カスタムレイアウト、または既存のコンポーネントライブラリへの統合が必要な場合は、ヘッドレスフックが適しています。CSS の上書きとカスタムプロパティは、手早くテーマを調整する場合に適しています。
</Tip>
