/* =====================================================================
   音声入力のボタンの共通の見た目（HxVoiceButton・change1006・2026-10-09・段 0）
   仕様 docs/voice-button-unify-spec-2026-10-07.md（「★ 本人の答え」の章・3 章「見た目の値」・8 章）。
   見本は /mock/voice-button（static/css/mock_voice_button.css の A）。

   - 押す前はどの画面も青の塗り（vb8 B・青い枠の形は使わない）。聞いている間は coral に紺の文字（vb2 A）
   - 色はブランドの変数（style.css :root）だけ。rgba・hex は color-mix が効かない古い Safari 向けの「代わり」として、
     同じプロパティの color-mix の行の直前にだけ書く（tests/test_voice_button_css.py が見る）
   - 大きさ（高さ・余白・文字の大きさ）は決めない。ボタンの大きさは各画面の CSS の今の値のまま
   - ボタンには Bootstrap の .btn を残す（この CSS が遅れて読まれても形は崩れない）
   ===================================================================== */

/* 1 待つ: 青の塗りに白い文字（4.68:1） */
.hx-voice-btn {
    --bs-btn-color: var(--bs-white);
    --bs-btn-bg: var(--helix-blue);
    --bs-btn-border-color: var(--helix-blue);
    --bs-btn-hover-color: var(--bs-white);
    --bs-btn-hover-bg: var(--helix-blue);
    --bs-btn-hover-border-color: var(--helix-blue);
    --bs-btn-active-color: var(--bs-white);
    --bs-btn-active-bg: var(--helix-blue);
    --bs-btn-active-border-color: var(--helix-blue);
    --bs-btn-disabled-color: var(--bs-white);
    --bs-btn-disabled-bg: var(--helix-blue);
    --bs-btn-disabled-border-color: var(--helix-blue);
    --bs-btn-disabled-opacity: .45;
    --bs-btn-focus-box-shadow: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--hx-voice-gap, 8px);
    white-space: nowrap;
}
.hx-voice-btn .bi { flex: 0 0 auto; line-height: 1; }
.hx-voice-btn .hx-voice-label { min-width: 0; word-break: auto-phrase; text-wrap: balance; }
/* 会話の順番の状態（相手が話しています ・ タップで話し始める）は「・」の後ろでだけ 2 行に分ける */
.hx-voice-btn .hx-voice-phrase { white-space: nowrap; }
/* 押す前と押したあとで、ボタンの幅を長いほうの言葉（音声入力を終了する）にそろえる（押す前と同じ大きさ・同じ場所・仕様 2-11）。
   長いほうの言葉を見えないまま高さ 0 でアイコンと言葉と同じ 1 段目に重ね、アイコンと言葉はその幅の真ん中に並べる
   （2 段目にすると、言葉が真ん中より上がる）。読み上げには入らない */
.btn.hx-voice-btn[data-hx-sizer] {
    display: inline-grid;
    grid-template-columns: auto auto;
    grid-template-rows: auto;
    justify-content: center;
    align-items: center;
    column-gap: var(--hx-voice-gap, 8px);
    row-gap: 0;
}
.btn.hx-voice-btn[data-hx-sizer] > .bi { grid-row: 1; grid-column: 1; justify-self: end; }
.btn.hx-voice-btn[data-hx-sizer] > .hx-voice-label { grid-row: 1; grid-column: 2; justify-self: start; }
.btn.hx-voice-btn[data-hx-sizer]::after {
    content: attr(data-hx-sizer);
    grid-row: 1;
    grid-column: 1 / -1;
    align-self: center;
    height: 0;
    padding-left: calc(1em + var(--hx-voice-gap, 8px));
    overflow: hidden;
    white-space: nowrap;
    visibility: hidden;
    pointer-events: none;
}
.hx-voice-btn:hover:not(:disabled):not([aria-disabled="true"]) {
    color: var(--bs-white);
    border-color: var(--helix-blue);
    background-color: #4B81F4;
    background-color: color-mix(in srgb, var(--helix-blue) 85%, var(--bs-white));
}
.hx-voice-btn:focus-visible,
.hx-voice-quiet:focus-visible {
    outline: 2px solid var(--helix-cyan);
    outline-offset: 2px;
    box-shadow: none;
}

/* 3 聞いています: coral の塗り、文字とアイコンは紺（--bg・6.51:1・vb2 A）。1.4 秒でゆっくり脈打つ */
.hx-voice-btn[data-hx-state="listening"] {
    --bs-btn-color: var(--bg);
    --bs-btn-bg: var(--coral);
    --bs-btn-border-color: var(--coral);
    --bs-btn-hover-color: var(--bg);
    --bs-btn-hover-bg: var(--coral);
    --bs-btn-hover-border-color: var(--coral);
    --bs-btn-active-color: var(--bg);
    --bs-btn-active-bg: var(--coral);
    --bs-btn-active-border-color: var(--coral);
    animation: hx-voice-pulse 1.4s ease-in-out infinite;
}
.hx-voice-btn[data-hx-state="listening"]:hover:not(:disabled):not([aria-disabled="true"]) {
    color: var(--bg);
    border-color: var(--coral);
    background-color: var(--coral);
}
@keyframes hx-voice-pulse {
    0%, 100% {
        box-shadow: 0 0 0 0 rgba(255, 107, 90, .5);
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--coral) 50%, transparent);
    }
    50% {
        box-shadow: 0 0 0 10px rgba(255, 107, 90, 0);
        box-shadow: 0 0 0 10px color-mix(in srgb, var(--coral) 0%, transparent);
    }
}

/* 2 準備中・6 確定中・7 採点中・12 使えない: 待つときと同じ色で .45。回る印は付けない。押せない間は脈打たない。
   取り消すの無い画面の準備中・確定中と会話の「相手が考えています…」は disabled でなく aria-disabled（フォーカスを残す）なので、同じ見た目にする */
.hx-voice-btn:disabled,
.hx-voice-btn[aria-disabled="true"] { opacity: .45; animation: none; pointer-events: auto; }
.hx-voice-btn:is([data-hx-state="preparing"], [data-hx-state="finalizing"], [data-hx-state="assessing"]) { cursor: progress; }
.hx-voice-btn[data-hx-state="off"] { cursor: not-allowed; }
.hx-voice-btn[data-hx-state="off"][data-hx-turn][aria-disabled="true"] { cursor: progress; }

/* 取り消す（静かなボタン）: 地・枠は透明、muted、アイコンなし。高さと余白は同じ行の主ボタンと同じ（画面の CSS） */
.hx-voice-quiet {
    --bs-btn-color: var(--text-muted);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: var(--text);
    --bs-btn-hover-bg: var(--surface2);
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-color: var(--text);
    --bs-btn-active-bg: var(--surface2);
    --bs-btn-active-border-color: transparent;
    --bs-btn-focus-box-shadow: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
}
.hx-voice-quiet[hidden] { display: none; }
.hx-voice-quiet .bi { display: none; }

/* 印（● 聞いています 経過 3秒）: 1 つのまとまりで折り返さない。読み上げない（aria-hidden）。
   間は採用済みの統合案（ラウンジの発音 #mic-meter・窓の .pp-meter）と同じ 12px */
.hx-voice-meter {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    flex-wrap: nowrap;
    white-space: nowrap;
    min-width: 0;
    font-size: 12px;
    line-height: 1.5;
}
.hx-voice-meter[hidden] { display: none; }
.hx-voice-dot {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--coral);
    animation: hx-voice-blink 1.4s ease-in-out infinite;
}
.hx-voice-dot[hidden] { display: none; }
@keyframes hx-voice-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: .35; }
}
.hx-voice-word { font-size: 12px; font-weight: 500; color: var(--text); }
/* 4 まもなく確定・5 上限が近い・会話の閉じるの知らせ: 言葉だけ amber（9.43:1） */
.hx-voice-meter[data-hx-tone="warn"] .hx-voice-word { color: var(--amber); }
.hx-voice-sec { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text); }
/* 経過の秒数には「経過」と書く（「あと 1 秒で確定」の残り秒と読み違えないため）。残り秒・上限の知らせの間は秒数ごと隠す */
.hx-voice-sec-tag { margin-right: 4px; color: var(--text-muted); }
/* 秒数の幅は、桁が増えても印の幅が変わらないよう取っておく（後ろの「取り消す」が数えるたびに動かない） */
.hx-voice-secval { display: inline-block; min-width: calc(2ch + 1em); }
.hx-voice-sec[hidden], .hx-voice-tail[hidden], .hx-voice-level[hidden] { display: none; }
.hx-voice-tail { color: var(--text-muted); }
/* 入力レベル（発音だけ）: 120×8px・地は --surface2。バーの色は画面の今のまま */
.hx-voice-level {
    flex: 0 0 120px;
    width: 120px;
    height: 8px;
    border-radius: 4px;
    background: var(--surface2);
    overflow: hidden;
}
.hx-voice-level > i { display: block; width: 0; height: 100%; background: var(--helix-cyan); transition: width .1s linear; }
/* 短い言葉（とても狭い幅 360px 以下だけ。会話の「自動で聞いています」→「自動」） */
:is(.hx-voice-status, .hx-voice-word) .hx-voice-short { display: none; }
@media (max-width: 360px) {
    :is(.hx-voice-status, .hx-voice-word) .hx-voice-long { display: none; }
    :is(.hx-voice-status, .hx-voice-word) .hx-voice-short { display: inline; }
}

/* 状態の行。頭に vi1 の方式の印、続けて確定の決まり（もう一度押すか、3 秒黙ると確定します。）と ✓ の行。
   ボタンのすぐ下で読めるよう 12px/1.75（統合案の発音の .cm-status・.pp-status-row は 11px のまま）。日本語は文節で折り返す。
   1 つの段落のように流す（狭い幅でも、印だけが 1 行に取り残されない） */
.hx-voice-statusline {
    display: block;
    min-height: 4px;
    margin-top: 8px;
    font-size: 12px;
    line-height: 1.75;
    word-break: auto-phrase;
    text-wrap: pretty;
    line-break: strict;
}
/* 方式の印（vi1）は折り返さない 1 まとまり（文字と色は voice_engine_label.js のまま） */
.hx-voice-statusline > .voice-engine-label { white-space: nowrap; margin-right: 8px; vertical-align: baseline; }
/* とても狭い幅（360px 以下）: 琥珀色の方式の印（ブラウザ内蔵・サーバーと理由）は、ピルの中で 2 行に割らず自分の 1 行に出す */
@media (max-width: 360px) {
    .hx-voice-statusline > .voice-engine-label:is([data-voice-engine="browser"], [data-voice-engine="server"]) {
        display: flex;
        width: fit-content;
        max-width: 100%;
        flex-wrap: nowrap;
        column-gap: .3em;
        margin-right: 0;
        padding-left: .4rem;
        padding-right: .4rem;
    }
}
/* 状態の行の頭に印を置く画面（アトリエ）: 印の行も文字だけの行と同じ高さ（12px × 1.75） */
.hx-voice-statusline > .hx-voice-meter { margin-right: 12px; line-height: 1.75; vertical-align: top; }
.hx-voice-status {
    min-width: 0;
    margin: 0;
    font-size: 12px;
    line-height: 1.75;
    color: var(--text-muted);
    overflow-wrap: anywhere;
    word-break: auto-phrase;
    text-wrap: pretty;
    line-break: strict;
}
.hx-voice-statusline > .hx-voice-status { display: inline; }
/* ✓ は数字とくっつけない（「✓3 秒」が「√3」に読めないように） */
.hx-voice-ok { margin-right: .2em; color: var(--helix-teal); }
/* ボタンの名前（「回答する」「言い直しを残す」）・「もう一度押すか、」は途中で折り返さない */
.hx-voice-keep { white-space: nowrap; }

/* 知らせの枠: エラー（coral・role=alert）と注意（amber・role=status）。次に押すまで残す（.ur-error・.pp-err と同じ形） */
.hx-voice-error {
    margin: 12px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--coral);
    color: var(--text);
    font-size: 13px;
    line-height: 1.8;
    text-align: left;
    overflow-wrap: anywhere;
    word-break: auto-phrase;
    text-wrap: pretty;
    line-break: strict;
    background: rgba(255, 107, 90, .08);
    background: color-mix(in srgb, var(--coral) 8%, transparent);
}
.hx-voice-error[hidden] { display: none; }
.hx-voice-error.is-notice {
    border-left-color: var(--amber);
    background: rgba(255, 179, 71, .08);
    background: color-mix(in srgb, var(--amber) 8%, transparent);
}
.hx-voice-error > span { display: block; }
.hx-voice-error .hx-voice-error-next { color: var(--text-muted); font-size: 12px; }

/* 発音練習の窓を開く入口（vb14 B・仕様 8 章）: 水色の枠の小さなピル。押すとすぐ聞き始める青いボタンとは形で分ける */
.hx-pron-launch {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
    padding: 6px 13px;
    border-radius: 99px;
    background: transparent;
    color: var(--helix-cyan);
    font: 500 13px/1.4 'Noto Sans JP', sans-serif;
    white-space: nowrap;
    cursor: pointer;
    border: 1px solid rgba(0, 212, 255, .45);
    border: 1px solid color-mix(in srgb, var(--helix-cyan) 45%, transparent);
}
.hx-pron-launch .bi { flex: 0 0 auto; line-height: 1; }
.hx-pron-launch:hover:not(:disabled):not([aria-disabled="true"]) {
    color: var(--helix-cyan);
    background: rgba(0, 212, 255, .12);
    background: color-mix(in srgb, var(--helix-cyan) 12%, transparent);
}
.hx-pron-launch:focus-visible { outline: 2px solid var(--helix-cyan); outline-offset: 2px; }
/* オフラインのときは押せない（title「発音練習はオンラインで利用できます」） */
.hx-pron-launch:disabled,
.hx-pron-launch[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
@media (pointer: coarse) { .hx-pron-launch { min-height: 44px; } }

/* 動きを減らす設定: 脈打ち・点の明滅・入力レベルの動きを止め、止まった 3px の輪にする */
@media (prefers-reduced-motion: reduce) {
    .hx-voice-btn[data-hx-state="listening"] {
        animation: none;
        box-shadow: 0 0 0 3px rgba(255, 107, 90, .35);
        box-shadow: 0 0 0 3px color-mix(in srgb, var(--coral) 35%, transparent);
    }
    .hx-voice-dot { animation: none; }
    .hx-voice-level > i { transition: none; }
}
