/* 🎙 Voice Standby — full-screen voice assistant (2026-05-30, v70.2 Gemini-level redesign)
 *
 * 對標 Gemini Live + ChatGPT Voice + Apple Siri（researcher report）：
 *   - 純黑底 + 流動 mesh gradient blob 背景
 *   - 中央 280px mesh gradient orb，4 個 radial blob 旋轉 + glass 高光
 *   - --orb-level CSS var（0-1）由 AnalyserNode RAF 寫，驅動 scale + ambient glow
 *   - 底部 3 鈕控制列：mute(52) / end(68 red) / replay(52)，間距均等
 *   - 紅圓 end 鈕最大，誤觸代價最高 → Fitts 反向應用
 *   - Transcript 緊湊一行，無 card，省得搶 orb 視覺
 *
 * L3 focus mode 守則 §22 — mobileLayer:'focus' 由 nxRouter 自動隱藏 tab bar，
 * 結束 = explicit「結束」按鈕 / 講「掰掰」 / 點 backdrop 確認，不靠返回鍵。
 *
 * Audio-reactive：app-voice-standby.js `_vsStartAudioReactive()` 起 AnalyserNode，
 * RAF loop 寫 --orb-level 到 .voice-standby root。CSS 用 calc/var 算 scale + opacity。
 */

/* ═══ Root layer ═══════════════════════════════════════════════════════ */
.voice-standby {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: max(20px, var(--safe-top) + 12px) 20px max(28px, var(--safe-bottom) + 20px);
  background: #050507;
  color: var(--text-primary, #e8e6f0);
  isolation: isolate;
  overflow: hidden;
  --orb-level: 0;  /* 0-1, written by JS RAF from AnalyserNode */
  animation: vs-enter 420ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
@keyframes vs-enter {
  from { opacity: 0; transform: scale(1.04); }
  to   { opacity: 1; transform: scale(1); }
}
.voice-standby[data-leaving] {
  animation: vs-leave 280ms cubic-bezier(0.4, 0, 1, 1) both;
}
@keyframes vs-leave {
  to { opacity: 0; transform: scale(0.96); }
}

/* ═══ Mesh gradient 背景 — 3 個 blob 慢速漂浮，營造空間感 ═══════════════ */
.vs-mesh {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
.vs-mesh-blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(60px);
  opacity: 0.45;
  will-change: transform;
}
.vs-mesh-blob--1 {
  top: -10%; left: -10%;
  width: 60vw; height: 60vw;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent, #8b7fd9) 70%, transparent) 0%, transparent 70%);
  animation: vs-mesh-1 22s ease-in-out infinite alternate;
}
.vs-mesh-blob--2 {
  bottom: -15%; right: -15%;
  width: 70vw; height: 70vw;
  background: radial-gradient(circle, color-mix(in srgb, #ff6b9d 60%, transparent) 0%, transparent 70%);
  animation: vs-mesh-2 26s ease-in-out infinite alternate;
}
.vs-mesh-blob--3 {
  top: 30%; right: -10%;
  width: 50vw; height: 50vw;
  background: radial-gradient(circle, color-mix(in srgb, #5ee0ff 55%, transparent) 0%, transparent 70%);
  animation: vs-mesh-3 18s ease-in-out infinite alternate;
  opacity: 0.32;
}
@keyframes vs-mesh-1 {
  from { transform: translate(0, 0) rotate(0deg); }
  to   { transform: translate(8vw, 6vh) rotate(40deg); }
}
@keyframes vs-mesh-2 {
  from { transform: translate(0, 0) rotate(0deg); }
  to   { transform: translate(-6vw, -8vh) rotate(-30deg); }
}
@keyframes vs-mesh-3 {
  from { transform: translate(0, 0); }
  to   { transform: translate(-10vw, 12vh); }
}

/* ═══ Header — mode tag + close X ═══════════════════════════════════════ */
.vs-header {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  animation: vs-fade-down 320ms cubic-bezier(0.2, 0.8, 0.2, 1) 80ms both;
}
@keyframes vs-fade-down {
  from { opacity: 0; transform: translateY(-8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vs-mode-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.7);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}
.vs-mode-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent, #8b7fd9);
  box-shadow: 0 0 6px color-mix(in srgb, var(--accent, #8b7fd9) 90%, transparent);
  animation: vs-mode-dot-pulse 1.6s ease-in-out infinite;
}
@keyframes vs-mode-dot-pulse {
  0%, 100% { opacity: 1;   transform: scale(1); }
  50%      { opacity: 0.5; transform: scale(0.7); }
}
.vs-close {
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.04);
  color: rgba(255, 255, 255, 0.6);
  border-radius: 50%;
  cursor: pointer;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: transform 80ms ease, background 160ms ease, color 160ms ease;
}
.vs-close:active { transform: scale(0.9); }
@media (hover: hover) {
  .vs-close:hover { background: rgba(255, 255, 255, 0.1); color: white; }
}

/* ═══ Stage — orb + hint + transcript ══════════════════════════════════ */
.vs-stage {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 24px;
  width: 100%;
  min-height: 0;
  padding: 12px 0;
  position: relative;
}

/* ─── Orb — Gemini-style mesh gradient sphere ───────────────────────────
 * 4 layer radial blob 漩渦旋轉 + glass 高光 + ambient outer glow
 * audio-reactive：scale = 1 + level * 0.18，ambient opacity 跟著
 */
.vs-orb {
  position: relative;
  width: 280px;
  height: 280px;
  display: flex;
  align-items: center;
  justify-content: center;
  --base-scale: 1;
  transform: scale(calc(var(--base-scale) + var(--orb-level) * 0.18));
  transition: transform 60ms linear;  /* fast LPF visual smoothing */
  /* DNA-4 morph：從 FAB 位置 + scale(~0.13) 長到中心 + scale(1)，呼應 hero DNA-4
     view-transition morph 的因果連續性。--vs-morph-dx/dy/scale 由 _vsApplyMorphVars() 寫入。
     720ms spring → 結束後（無 fill-mode）回到 base transform，audio-reactive 接手繼續驅動 scale。
     `backwards` 只 fill 動畫**前**（delay 期 — 這裡無 delay 所以視覺無影響，但保險），
     **不**用 forwards/both — 否則 .vs-orb 的 base transform 會被 freeze，--orb-level 失效。 */
  animation: vs-orb-morph-in 720ms cubic-bezier(0.34, 1.4, 0.5, 1) backwards,
             vs-orb-float 6s ease-in-out 1.2s infinite;
}
@keyframes vs-orb-morph-in {
  0% {
    opacity: 0.55;
    transform: translate(var(--vs-morph-dx, 0px), var(--vs-morph-dy, 180px))
               scale(var(--vs-morph-scale, 0.13));
  }
  60% {
    opacity: 1;
  }
  100% {
    opacity: 1;
    /* 100% 不用 calc — 動畫結束 → 無 fill-mode → 自動回 .vs-orb base transform
       (scale(calc(--base-scale + --orb-level*0.18)))，audio-reactive 接手 */
    transform: translate(0, 0) scale(1);
  }
}
@keyframes vs-orb-float {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -8px; }
}

/* Mesh blob — 4 個 radial 在 orb 內部旋轉融合成多彩漩渦
   每個 blob 偏移到不同角度，conic 整體 spin → mesh gradient 視覺效果 */
.vs-orb-blob {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  filter: blur(16px);
  mix-blend-mode: screen;
  will-change: transform;
}
.vs-orb-blob--cyan {
  background: radial-gradient(circle at 30% 30%, #5ee0ff 0%, transparent 55%);
  animation: vs-orb-rot-1 9s linear infinite;
}
.vs-orb-blob--magenta {
  background: radial-gradient(circle at 70% 35%, #ff6b9d 0%, transparent 55%);
  animation: vs-orb-rot-2 11s linear infinite;
}
.vs-orb-blob--gold {
  background: radial-gradient(circle at 30% 70%, #ffc56e 0%, transparent 55%);
  animation: vs-orb-rot-3 13s linear infinite;
  opacity: 0.7;
}
.vs-orb-blob--accent {
  background: radial-gradient(circle at 70% 70%, var(--accent, #8b7fd9) 0%, transparent 55%);
  animation: vs-orb-rot-4 7s linear infinite;
}
@keyframes vs-orb-rot-1 { to { transform: rotate(360deg); } }
@keyframes vs-orb-rot-2 { to { transform: rotate(-360deg); } }
@keyframes vs-orb-rot-3 { to { transform: rotate(360deg); } }
@keyframes vs-orb-rot-4 { to { transform: rotate(-360deg); } }

/* Glass 表面 — 球體 sheen + 頂部反光，讓 mesh 看起來像「在球面上流動」 */
.vs-orb-glass {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%,
      rgba(255, 255, 255, 0.45) 0%,
      rgba(255, 255, 255, 0.1) 18%,
      transparent 40%),
    radial-gradient(circle at center,
      transparent 60%,
      rgba(0, 0, 0, 0.35) 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.08),
    inset 0 -8px 40px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* Ambient glow — orb 外圍光暈，audio-reactive opacity */
.vs-orb-ambient {
  position: absolute;
  inset: -80px;
  border-radius: 50%;
  background: radial-gradient(circle,
    color-mix(in srgb, var(--accent, #8b7fd9) 55%, transparent) 0%,
    transparent 60%);
  filter: blur(40px);
  opacity: calc(0.35 + var(--orb-level) * 0.85);
  transition: opacity 80ms linear;
  pointer-events: none;
  animation: vs-orb-ambient-breath 4s ease-in-out infinite;
}
@keyframes vs-orb-ambient-breath {
  0%, 100% { transform: scale(0.92); }
  50%      { transform: scale(1.08); }
}

/* Ripple rings — listening / speaking 時擴散 */
.vs-orb-ripple {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 1.5px solid color-mix(in srgb, var(--accent, #8b7fd9) 50%, transparent);
  opacity: 0;
  pointer-events: none;
}

/* ═══ State variants ═══════════════════════════════════════════════════ */

/* listening — 緩 ripple 擴散 */
.voice-standby[data-state="listening"] .vs-orb-ripple {
  animation: vs-ripple 3s ease-out infinite;
}
.voice-standby[data-state="listening"] .vs-orb-ripple--1 { animation-delay: 0s; }
.voice-standby[data-state="listening"] .vs-orb-ripple--2 { animation-delay: 1s; }
.voice-standby[data-state="listening"] .vs-orb-ripple--3 { animation-delay: 2s; }
@keyframes vs-ripple {
  0%   { opacity: 0.55; transform: scale(1); border-width: 1.5px; }
  100% { opacity: 0;    transform: scale(1.6); border-width: 0.5px; }
}

/* thinking — base scale 縮 + mesh 加速 + 無 ripple */
.voice-standby[data-state="thinking"] .vs-orb {
  --base-scale: 0.88;
}
.voice-standby[data-state="thinking"] .vs-orb-blob {
  animation-duration: 2.4s, 2.4s, 2.4s, 2.4s;
}
.voice-standby[data-state="thinking"] .vs-orb-blob--cyan    { animation: vs-orb-rot-1 2.8s linear infinite; }
.voice-standby[data-state="thinking"] .vs-orb-blob--magenta { animation: vs-orb-rot-2 3.4s linear infinite; }
.voice-standby[data-state="thinking"] .vs-orb-blob--gold    { animation: vs-orb-rot-3 4s   linear infinite; }
.voice-standby[data-state="thinking"] .vs-orb-blob--accent  { animation: vs-orb-rot-4 2.2s linear infinite; }

/* speaking — base scale 放大 + ripple 加速 */
.voice-standby[data-state="speaking"] .vs-orb {
  --base-scale: 1.05;
}
.voice-standby[data-state="speaking"] .vs-orb-ripple {
  animation: vs-ripple 1.4s ease-out infinite;
}
.voice-standby[data-state="speaking"] .vs-orb-ripple--1 { animation-delay: 0s; }
.voice-standby[data-state="speaking"] .vs-orb-ripple--2 { animation-delay: 0.45s; }
.voice-standby[data-state="speaking"] .vs-orb-ripple--3 { animation-delay: 0.9s; }
.voice-standby[data-state="speaking"] .vs-orb-ambient {
  /* speaking 時忽略 mic level（沒在聽），fixed amplitude pulse */
  opacity: 0.8;
  animation-duration: 0.9s;
}

/* ═══ State hint — Pi.ai 風小字 ════════════════════════════════════════ */
.vs-state-hint {
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.6);
  text-align: center;
  letter-spacing: 0.04em;
  min-height: 1.3em;
  animation: vs-fade-up 380ms cubic-bezier(0.2, 0.8, 0.2, 1) 360ms both;
}

/* ═══ Transcript — 無框、緊湊、字小 ════════════════════════════════════ */
.vs-transcript {
  max-width: min(94vw, 480px);
  font-size: 14px;
  line-height: 1.5;
  text-align: center;
  color: rgba(255, 255, 255, 0.95);
  animation: vs-fade-up 240ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.vs-transcript-final {
  color: white;
  font-weight: 500;
}
.vs-transcript-interim {
  color: rgba(255, 255, 255, 0.45);
  font-style: italic;
}
@keyframes vs-fade-up {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ═══ AI response — 緊湊一段，無 card，最大 4 行 scroll ═════════════════ */
.vs-response {
  max-width: min(92vw, 500px);
  padding: 0 8px;
  animation: vs-fade-up 380ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.vs-response-text {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.82);
  text-align: center;
  word-break: break-word;
  max-height: 6em;
  overflow-y: auto;
}

/* ═══ Footer — Gemini-style 3 鈕控制列 ═════════════════════════════════ */
.vs-footer {
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  animation: vs-fade-up 340ms cubic-bezier(0.2, 0.8, 0.2, 1) 480ms both;
}

.vs-turn-anchor {
  font-size: 11px;
  color: rgba(255, 255, 255, 0.4);
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* 3 鈕橫排，均等間距 — Gemini Live pattern */
.vs-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 28px;
}

.vs-ctrl {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  cursor: pointer;
  position: relative;
  transition: transform 100ms cubic-bezier(0.34, 1.56, 0.64, 1),
              background 180ms ease,
              box-shadow 180ms ease,
              color 180ms ease;
}
.vs-ctrl:active { transform: scale(0.93); }
.vs-ctrl:disabled { opacity: 0.35; cursor: not-allowed; }
.vs-ctrl:focus-visible {
  outline: 2px solid var(--accent, #8b7fd9);
  outline-offset: 3px;
}

/* 左：mute mic — 52px 圓鈕 */
.vs-ctrl--mute {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: white;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
@media (hover: hover) {
  .vs-ctrl--mute:hover { background: rgba(255, 255, 255, 0.14); }
}
.vs-ctrl--mute.is-muted {
  background: rgba(255, 80, 80, 0.18);
  border-color: rgba(255, 80, 80, 0.45);
  color: #ff9a9a;
}

/* 中：end — 68px 紅圓最大，視覺主角 */
.vs-ctrl--end {
  width: 68px;
  height: 68px;
  border-radius: 50%;
  background: linear-gradient(140deg, #ff4d4d 0%, #d93636 100%);
  color: white;
  box-shadow:
    0 8px 24px rgba(255, 60, 60, 0.4),
    0 0 0 4px rgba(255, 60, 60, 0.12),
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    inset 0 -2px 0 rgba(0, 0, 0, 0.15);
}
@media (hover: hover) {
  .vs-ctrl--end:hover {
    box-shadow:
      0 10px 28px rgba(255, 60, 60, 0.55),
      0 0 0 6px rgba(255, 60, 60, 0.18),
      inset 0 1px 0 rgba(255, 255, 255, 0.35),
      inset 0 -2px 0 rgba(0, 0, 0, 0.15);
  }
}
.vs-ctrl--end.is-loading { color: transparent; }
.vs-ctrl--end .vs-ctrl-spinner {
  display: none;
  position: absolute;
  inset: 0;
  margin: auto;
  width: 22px;
  height: 22px;
  border: 2.5px solid rgba(255, 255, 255, 0.35);
  border-top-color: white;
  border-radius: 50%;
  animation: vs-spin 0.8s linear infinite;
}
.vs-ctrl--end.is-loading .vs-ctrl-spinner { display: block; }
@keyframes vs-spin {
  to { transform: rotate(360deg); }
}

/* 右：replay — 52px 圓鈕 */
.vs-ctrl--replay {
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}
@media (hover: hover) {
  .vs-ctrl--replay:hover:not(:disabled) { background: rgba(255, 255, 255, 0.14); color: white; }
}

.vs-end-hint {
  margin: 0;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.35);
  letter-spacing: 0.04em;
}

/* ═══ 🔑 Key-missing 攔截 — BYO OpenAI key 未設定 ═══════════════════════ */
.vs-keymiss {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(5, 5, 8, 0.85);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  animation: vs-fade-up 320ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.vs-keymiss-card {
  max-width: 360px;
  width: 100%;
  padding: 28px 24px 22px;
  background: linear-gradient(160deg,
    color-mix(in srgb, var(--accent, #8b7fd9) 14%, rgba(20, 16, 36, 0.95)) 0%,
    rgba(12, 10, 22, 0.95) 100%);
  border: 1px solid color-mix(in srgb, var(--accent, #8b7fd9) 32%, transparent);
  border-radius: 22px;
  box-shadow:
    0 24px 64px rgba(0, 0, 0, 0.6),
    0 0 0 1px color-mix(in srgb, var(--accent, #8b7fd9) 16%, transparent),
    0 0 80px color-mix(in srgb, var(--accent, #8b7fd9) 20%, transparent);
  text-align: center;
}
.vs-keymiss-icon {
  width: 56px;
  height: 56px;
  margin: 0 auto 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: color-mix(in srgb, var(--accent, #8b7fd9) 22%, transparent);
  color: color-mix(in srgb, var(--accent, #8b7fd9) 95%, white);
  border: 1px solid color-mix(in srgb, var(--accent, #8b7fd9) 35%, transparent);
}
.vs-keymiss-icon--warn {
  background: rgba(255, 168, 75, 0.18);
  color: #ffa84b;
  border-color: rgba(255, 168, 75, 0.35);
}
.vs-keymiss-body--turns {
  margin-top: -10px;
  margin-bottom: 16px;
  color: rgba(255, 255, 255, 0.55);
  font-size: 12.5px;
}
.vs-keymiss-title {
  margin: 0 0 10px;
  font-size: 18px;
  font-weight: 700;
  color: white;
  letter-spacing: 0.01em;
}
.vs-keymiss-body {
  margin: 0 0 22px;
  font-size: 13.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.75);
}
.vs-keymiss-actions {
  display: flex;
  gap: 10px;
  margin-bottom: 14px;
}
.vs-keymiss-btn {
  flex: 1;
  padding: 11px 16px;
  border-radius: 12px;
  border: 1px solid transparent;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: transform 80ms ease, background 160ms ease, border-color 160ms ease;
}
.vs-keymiss-btn:active { transform: scale(0.97); }
.vs-keymiss-btn--primary {
  background: var(--accent, #8b7fd9);
  color: white;
  box-shadow: 0 4px 14px color-mix(in srgb, var(--accent, #8b7fd9) 40%, transparent);
}
@media (hover: hover) {
  .vs-keymiss-btn--primary:hover {
    background: color-mix(in srgb, var(--accent, #8b7fd9) 90%, white);
  }
}
.vs-keymiss-btn--ghost {
  background: rgba(255, 255, 255, 0.06);
  color: rgba(255, 255, 255, 0.85);
  border-color: rgba(255, 255, 255, 0.1);
}
@media (hover: hover) {
  .vs-keymiss-btn--ghost:hover { background: rgba(255, 255, 255, 0.12); }
}
.vs-keymiss-hint {
  margin: 0;
  font-size: 11px;
  color: rgba(255, 255, 255, 0.4);
  line-height: 1.5;
}

/* ═══ Mobile tweaks ════════════════════════════════════════════════════ */
@media (max-width: 380px) {
  .vs-orb { width: 220px; height: 220px; }
  .vs-orb-ambient { inset: -60px; }
  .vs-ctrl--end { width: 60px; height: 60px; }
  .vs-controls { gap: 22px; }
}

/* ═══ Reduced-motion (a11y) ════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .voice-standby,
  .vs-orb,
  .vs-orb-blob,
  .vs-orb-ambient,
  .vs-orb-ripple,
  .vs-mode-dot,
  .vs-mesh-blob,
  .vs-header,
  .vs-state-hint,
  .vs-transcript,
  .vs-response,
  .vs-footer {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
  }
  .vs-orb { transform: none !important; }
}

/* FAB-area CSS（is-arming-standby / qa-floating-arming / qa-gesture-rail）
   已搬到 style/mobile/quick-add.css，那是 FAB 視覺的家。voice-standby.css 只負責 modal 本身。
   (v70.5, 2026-05-30 — 拆檔避免 §4 800 行上限) */
