/* ================================================================================
 * ファイル名: app/assets/stylesheets/voice_input.css
 * 概要: タスクフォーム（カンバンのタスク追加/編集モーダル）の音声入力マイクボタンの意匠。
 * 作成日: 2026-06-22
 *
 * 【リファクタリング基準】※コメント行は行数カウントから除外（CSS基準）
 *   1. 500行未満: 完璧  2. 800行未満: 問題なし  3. 1200行未満: 注意喚起・要検討  4. 1200行以上: 必須
 *   現状: 実コード約150行（2026-06-23 計測）→ 判定: 完璧（500行未満）
 *
 * 対象: app/views/app/task_projects/_voice_input_button.html.erb
 *       （タイトル欄＝.kanban-input-wrapper 内 / 説明欄＝.markdown-editor-header 内）
 * 方針:
 *   - 色・余白・角丸はデザイントークン（--gold-* / --color-* / --radius-* / --space-* /
 *     --text-* / --border-*）経由（ハードコード禁止）。
 *   - 配置は論理プロパティ（inset-inline-end / margin-inline）で RTL（ar-SA）に自動追従。
 *   - 録音中のパルスは prefers-reduced-motion を尊重（reduce では非アニメの色表現にフォールバック）。
 *   - status は sr-only（role=status aria-live=polite）で状態遷移をスクリーンリーダーへ通知。
 *     視覚フィードバックはボタンの録音状態（色/パルス）で表現する。
 * ================================================================================ */

.voice-input {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
}

/* マイクボタン本体（アイコンのみ） */
.voice-input__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--gold-border-subtle);
  border-radius: var(--radius-full);
  background: transparent;
  /* アイコン色（stroke=currentColor）はテーマ追従の文字用ゴールドを使う。
     var(--gold-primary) は Light テーマで白背景に 1.33:1 となり不可視（Phase F-7 不変条件）。 */
  color: var(--lx-gold-text);
  cursor: pointer;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}

.voice-input__btn:hover {
  background: rgba(var(--gold-primary-rgb), 0.12);
  border-color: var(--gold-border-medium);
}

.voice-input__btn:focus-visible {
  outline: 2px solid var(--lx-gold-text);
  outline-offset: 2px;
}

.voice-input__icon {
  width: 18px;
  height: 18px;
}

/* 録音中: 危険色（赤）で「録音している」ことを明示。 */
.voice-input__btn--recording {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background: rgba(var(--color-danger-rgb), 0.12);
}

/* status は視覚的に隠す（aria-live でスクリーンリーダーへ通知）。 */
.voice-input__status {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ===== タイトル欄（.kanban-input-wrapper 内）: 入力欄末尾に重ねて配置 ===== */
.kanban-input-wrapper > .voice-input {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 8px;
  transform: translateY(-50%);
}

/* マイクと入力テキストが重ならないよう末尾に余白を確保（マイクがある入力のみ）。 */
.kanban-input-wrapper:has(> .voice-input) > .kanban-form-input {
  padding-inline-end: 44px;
}

/* ===== 説明欄: プレビュー/編集タブ行の「編集」の右隣に配置 ===== */
.markdown-toggle-tabs > .voice-input {
  align-self: center; /* タブ行の高さに対して縦中央に揃える */
}

/* ===== 自動付与（共通化）: アプリ全体の自由記述欄に JS が後付けするラッパー =====
   voice_input_autoattach_controller.js が対象欄を <span.voice-input-field-wrap> で
   包み、末尾にマイクを絶対配置する。input は縦中央、textarea は上端寄せ。 */
.voice-input-field-wrap {
  position: relative;
  display: block;
}
.voice-input-field-wrap > .voice-input {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-end: 8px;
  transform: translateY(-50%);
}
.voice-input-field-wrap--textarea > .voice-input {
  inset-block-start: 8px;
  transform: none; /* textarea は背が高いので上端寄せ */
}
/* マイクと入力テキストが重ならないよう末尾に余白を確保。 */
.voice-input-field-wrap:has(> .voice-input) > input,
.voice-input-field-wrap:has(> .voice-input) > textarea {
  padding-inline-end: 40px;
}

/* ===== コメント欄（textarea を含むラッパー）: 右上にマイク、本文と重ならない余白を確保 ===== */
.kanban-input-wrapper:has(> .kanban-form-textarea) > .voice-input {
  inset-block-start: 8px;
  transform: none; /* textarea は背が高いので縦中央でなく上端寄せにする */
}
.kanban-input-wrapper:has(> .voice-input) > .kanban-form-textarea {
  padding-inline-end: 44px;
}

/* ===== 録音中パルス（モーション可のときのみ） ===== */
@media (prefers-reduced-motion: no-preference) {
  .voice-input__btn--recording {
    animation: voice-input-pulse 1.4s ease-in-out infinite;
  }

  @keyframes voice-input-pulse {
    0%, 100% {
      box-shadow: 0 0 0 0 rgba(var(--color-danger-rgb), 0.45);
    }
    50% {
      box-shadow: 0 0 0 6px rgba(var(--color-danger-rgb), 0);
    }
  }
}

/* ===== 音声検知中の反応（声を拾えていることを視覚化） =====
   待機中（recording 単独）の穏やかな点滅に対し、検知中（recording + active）は
   拡大＋強いグローで明確に反応する。モーション低減時は静的な強調にフォールバック。 */
.voice-input__btn--recording.voice-input__btn--active {
  color: var(--color-danger);
  border-color: var(--color-danger);
  background: rgba(var(--color-danger-rgb), 0.18);
  box-shadow: 0 0 0 4px rgba(var(--color-danger-rgb), 0.28), 0 0 12px 3px rgba(var(--color-danger-rgb), 0.5);
}

@media (prefers-reduced-motion: no-preference) {
  /* 検知中は速く大きく反応（recording 単独のパルスより優先）。 */
  .voice-input__btn--recording.voice-input__btn--active {
    animation: voice-input-active 0.55s ease-in-out infinite;
  }

  @keyframes voice-input-active {
    0%, 100% {
      transform: scale(1.05);
      box-shadow: 0 0 0 3px rgba(var(--color-danger-rgb), 0.30), 0 0 10px 2px rgba(var(--color-danger-rgb), 0.45);
    }
    50% {
      transform: scale(1.16);
      box-shadow: 0 0 0 7px rgba(var(--color-danger-rgb), 0), 0 0 18px 5px rgba(var(--color-danger-rgb), 0.65);
    }
  }
}

/* タイトル欄のマイクは縦中央配置（transform: translateY(-50%)）のため、
   検知中の scale で配置がズレないよう translate を維持したスケールにする。 */
.kanban-input-wrapper > .voice-input .voice-input__btn--active {
  transform-origin: center;
}

/* ===== レスポンシブ（docs/responsive_design_plan.md 準拠 / 2026-06-23） =====
   モバイル（≤768px）ではマイクのタップターゲットを規約の 44x44px まで拡大し、
   入力欄の末尾余白も合わせて広げてテキストとの重なりを防ぐ。
   デスクトップ（769px+）は従来の 32px を維持する（既存挙動不変）。 */
@media (max-width: 768px) {
  .voice-input__btn {
    width: 44px;
    height: 44px;
  }

  .voice-input__icon {
    width: 22px;
    height: 22px;
  }

  /* 44px マイク（末端 inset 8px）に合わせ、入力テキストが裏に回らないよう余白を拡大。 */
  .kanban-input-wrapper:has(> .voice-input) > .kanban-form-input,
  .kanban-input-wrapper:has(> .voice-input) > .kanban-form-textarea,
  .voice-input-field-wrap:has(> .voice-input) > input,
  .voice-input-field-wrap:has(> .voice-input) > textarea {
    padding-inline-end: 56px;
  }

  /* 説明欄タブ行: マイク追加で詰まる狭幅・長語ロケールに備え、マイク所有行のみ折返しを許可。 */
  .markdown-toggle-tabs:has(> .voice-input) {
    flex-wrap: wrap;
    gap: var(--space-sm);
  }
}
