/* hayakuchi.css
   Styles for the additions to 早口言葉 (hayakuchi/): mic device selection +
   level meter, and the custom/AI tongue-twister repertoire (tabs, forms,
   AI candidate cards). Loaded after ../css/app.css from
   hayakuchi/index.html and reuses its CSS custom properties (--accent,
   --surface, --tap-min, etc.) so this stays visually consistent with the
   rest of the app rather than introducing a second palette.

   Per the file-ownership rule for this task: new styles for hayakuchi/ go
   here, not into ../css/app.css (which another workstream owns). */

/* -------------------- mic status (display-only, 2026-08-31) --------------
   Mic *selection* was removed in favor of Chrome's own mic setting (see
   js/mic-devices.js's file header comment) -- this now just names whichever
   device getUserMedia actually opened. */

.mic-panel {
  margin-bottom: 16px;
}

.mic-name-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 12px;
}

.mic-name-label {
  font-size: 1.05rem;
  font-weight: 700;
}

.mic-name-value {
  font-size: 1.05rem;
  color: var(--ink-muted);
}

.mic-meter-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}

.mic-meter {
  flex: 1 1 auto;
  height: 22px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  overflow: hidden;
}

.mic-meter-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 999px;
  transition: width 0.08s linear, background-color 0.15s linear;
}

.mic-meter-fill.loud {
  background: var(--success);
}

.mic-meter-label {
  flex: none;
  font-size: 0.95rem;
  color: var(--ink-muted);
  min-width: 84px;
  text-align: right;
}

.mic-recognition-note {
  font-size: 0.95rem;
}

#mic-check-btn {
  margin-bottom: 10px;
}

/* -------------------- tabs (定番 / 自分のレパートリー) -------------------- */
/* Reuses app.css's .option-row + button[aria-pressed="true"] pattern
   (same as the difficulty pickers in eye-training/) instead of inventing a
   second tab style. */

.phrase-tabs {
  margin-bottom: 16px;
}

.phrase-tabs button {
  font-size: 1.1rem;
  font-weight: 700;
}

/* -------------------- custom repertoire panel -------------------- */

.custom-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 16px;
}

.custom-actions button {
  flex: 1 1 200px;
}

.custom-empty-notice {
  text-align: center;
  padding: 8px 4px 20px;
}

.custom-phrase-list .phrase-item {
  flex-wrap: wrap;
  align-items: flex-start;
}

.custom-phrase-controls {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  width: 100%;
}

.custom-phrase-controls button {
  flex: 1 1 auto;
  min-height: 44px;
  font-size: 0.95rem;
  padding: 8px 12px;
}

.custom-phrase-badge {
  flex: none;
  font-size: 0.8rem;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--surface-2);
  color: var(--ink-muted);
}

.custom-phrase-badge.ai {
  background: var(--success-bg);
  color: var(--success);
}

/* -------------------- forms (自分で作る / AI生成) -------------------- */

.form-field {
  margin-bottom: 16px;
}

.form-field label {
  display: block;
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 6px;
}

.form-field textarea,
.form-field input[type="text"],
.form-field input[type="number"] {
  width: 100%;
  font-family: inherit;
  font-size: 1.15rem;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  min-height: var(--tap-min);
  resize: vertical;
}

.form-field textarea {
  line-height: 1.7;
}

.form-hint {
  font-size: 0.95rem;
  color: var(--ink-muted);
  margin-top: 6px;
}

/* -------------------- AI candidate cards -------------------- */

.ai-candidates {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 12px;
}

.ai-candidate-card {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}

.ai-candidate-text {
  font-size: 1.2rem;
  line-height: 1.7;
  margin-bottom: 4px;
}

.ai-candidate-meta {
  font-size: 0.95rem;
  color: var(--ink-muted);
  margin-bottom: 10px;
}

.ai-candidate-actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}

.ai-candidate-actions button {
  flex: 1 1 auto;
}

.ai-status {
  min-height: 1.4em;
}

/* -------------------- 固定操作バー (2026-09-01) --------------------
   選ぶ→上の録音ボタンまで戻る、という往復スクロールをなくすための対応。
   一覧セクション(#phrase-picker-section)が見えていて、かつ元の録音ボタン
   (#record-section)が画面外に出ているあいだだけ hayakuchi/app.js が
   #phrase-action-bar の hidden を外す。ボタン自体は状態を持たず、
   既存の #record-btn をクリックするだけ(録音の状態遷移は増やさない)。 */

.phrase-action-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: 0 -2px 10px rgba(16, 16, 16, 0.12);
}

/* [hidden] is a user-agent rule, easily out-specificity'd by an author rule
   that sets `display` on the same element -- restate it explicitly so the
   `.phrase-action-bar { display: flex }` above doesn't defeat `hidden`. */
.phrase-action-bar[hidden] {
  display: none;
}

.phrase-action-bar-text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--ink);
}

.phrase-action-bar-btn {
  flex: none;
  min-height: 64px;
  font-size: 1.15rem;
  padding: 10px 20px;
}

/* Reserve room at the foot of the page so the fixed bar never covers the
   last item of either phrase list while it's showing. */
.app.phrase-bar-open {
  padding-bottom: calc(110px + env(safe-area-inset-bottom));
}

/* Both this bar and the global feedback footer are position:fixed/bottom:0
   -- avoid stacking two fixed bars on a small phone screen by hiding the
   feedback footer while the action bar is showing. It comes back as soon as
   the list scrolls out of view or a recording starts. */
.app.phrase-bar-open .feedback-footer {
  display: none;
}

/* -------------------- 診断ログ送信 -------------------- */

.diag-report {
  margin-top: 24px;
  text-align: center;
}

.diag-report .card {
  margin-top: 12px;
  text-align: left;
}

/* -------------------- live match view (2026-09-03) --------------------
   Client request: show HOW the recognizer is matching the target phrase in
   real time, not just the raw recognized text. See hayakuchi/app.js's
   updateLiveMatch()/renderMatchRow() for the logic; this is display only.
   Sized for the 40-50代 target demographic -- large characters, generous
   spacing, high-contrast hit/miss colors rather than a subtle shade
   difference (a light gray on white "not yet matched" state would be too
   easy to miss at a glance while mid-recording). */

.live-match {
  border-radius: var(--radius-sm);
  padding: 16px 18px;
  margin-bottom: 16px;
  border: 1px solid var(--border);
  background: var(--surface-2);
}

.live-match-row {
  display: flex;
  flex-wrap: wrap; /* long phrases wrap to multiple lines rather than overflow */
  gap: 6px;
  margin-bottom: 10px;
}

.live-match-char {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.9em;
  padding: 0.15em 0.05em;
  border-radius: var(--radius-sm);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1.5;
  /* Under 150ms and capped further by css/app.css's global
     prefers-reduced-motion rule (transition-duration: 0.001ms !important) --
     kept short and optional rather than required, per the task's reduced-
     motion note. */
  transition: background-color 120ms ease, color 120ms ease;
}

.live-match-char.hit {
  background: var(--accent);
  color: var(--accent-contrast);
}

.live-match-char.miss {
  background: var(--surface);
  color: var(--ink-muted);
  border: 1px solid var(--border);
}

.live-match-count {
  margin: 0 0 10px;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink-2);
}

/* The raw "聞き取り中: ..." line nested inside #live-match no longer needs
   its own outer margin/border -- #live-match already supplies both -- so
   drop the .notice styling that would otherwise double it up. */
.live-match .notice {
  margin-bottom: 0;
  padding: 0;
  border: none;
  background: transparent;
  font-size: 0.95rem;
  color: var(--ink-muted);
}
