/* ===========================================================================
   問題集 — assets/quiz.css
   DESIGN.md のトークン・タイポ・スペーシング・角丸・モーション規約を複製して使う。
   ルート(../)の assets/styles.css は import しない（file:// でも独立して動くように）。
   =========================================================================== */

:root {
  color-scheme: light dark;
  --bg: #F5F5F7;
  --surface: #FFFFFF;
  --surface-2: #F4F4F7;
  --text: #1D1D1F;
  --text-2: #6E6E73;
  --text-3: #A1A1A6;
  --separator: rgba(0, 0, 0, 0.08);
  --accent: #0071E3;
  --accent-soft: rgba(0, 113, 227, 0.12);
  --success: #34C759;
  --success-soft: rgba(52, 199, 89, 0.16);
  --warn: #FF9F0A;
  --danger: #FF3B30;
  --danger-soft: rgba(255, 59, 48, 0.14);
  --ring-track: rgba(0, 0, 0, 0.06);
  --shadow-card: 0 1px 2px rgba(0, 0, 0, .04), 0 10px 30px rgba(0, 0, 0, .06);

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Hiragino Sans", "Noto Sans JP", sans-serif;

  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --dur-fast: 180ms;
  --dur: 280ms;
  --dur-slow: 460ms;

  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-pill: 999px;

  --pad-page: 16px;
  --maxw: 680px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #000000;
    --surface: #1C1C1E;
    --surface-2: #2C2C2E;
    --text: #F5F5F7;
    --text-2: #AEAEB2;
    --text-3: #6E6E73;
    --separator: rgba(255, 255, 255, 0.10);
    --accent: #0A84FF;
    --accent-soft: rgba(10, 132, 255, 0.18);
    --success: #30D158;
    --success-soft: rgba(48, 209, 88, 0.22);
    --warn: #FFD60A;
    --danger: #FF453A;
    --danger-soft: rgba(255, 69, 58, 0.22);
    --ring-track: rgba(255, 255, 255, 0.12);
    --shadow-card: none;
  }
}

/* --- reset ------------------------------------------------------------------ */
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  padding:
    env(safe-area-inset-top) env(safe-area-inset-right)
    env(safe-area-inset-bottom) env(safe-area-inset-left);
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 6px;
}

/* --- layout ------------------------------------------------------------------ */
.qz-app {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 8px var(--pad-page) 48px;
}

@media (min-width: 480px) {
  .qz-app {
    --pad-page: 20px;
  }
}

.qz-page {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* --- card --------------------------------------------------------------------- */
.qz-card {
  background: var(--surface);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
  padding: 20px;
}

@media (prefers-color-scheme: dark) {
  .qz-card {
    border: 1px solid var(--separator);
  }
}

/* --- header (home) ------------------------------------------------------------ */
.qz-header {
  padding: 16px 4px 8px;
}

/* ダッシュボードへの戻り。既存の .qz-back（画面内の戻る）と同じ控えめさに揃える。 */
.qz-header__back {
  display: inline-block;
  margin-bottom: 6px;
  font-size: 13px;
  color: var(--text-2);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-out);
}

.qz-header__back:hover {
  color: var(--accent);
}

.qz-header__title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.qz-header__caption {
  margin-top: 2px;
  font-size: 13px;
  color: var(--text-2);
}

/* --- home tabs / rounds ------------------------------------------------------- */
/* タブはヘッダ直下の2択だけに留める。カードを増やさず、現在地は塗りつぶしと
   aria-selected の両方で分かるようにする。 */
.qz-home-tabs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(125px, 1fr));
  gap: 4px;
  margin-top: 14px;
  padding: 4px;
  border-radius: var(--r-md);
  background: var(--surface-2);
}

.qz-prompt-settings { padding: 20px; overflow-wrap: anywhere; }
.qz-prompt-settings label { display: grid; gap: 8px; margin: 18px 0; }
.qz-prompt-settings input, .qz-prompt-settings textarea, .qz-prompt-settings select {
  width: 100%; min-width: 0; box-sizing: border-box; padding: 12px;
  color: var(--text); background: var(--surface); border: 1px solid var(--text-2);
  border-radius: 6px; font: inherit; line-height: 1.6;
}
.qz-prompt-settings textarea { resize: vertical; }
.qz-prompt-settings p { line-height: 1.8; }
.qz-prompt-settings .qz-editor__actions { display: flex; flex-wrap: wrap; gap: 8px; }

.qz-home-tab {
  min-height: 44px;
  padding: 8px 12px;
  border-radius: var(--r-sm);
  color: var(--text-2);
  font-size: 14px;
  font-weight: 600;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out),
    box-shadow var(--dur-fast) var(--ease-out);
}

.qz-home-tab[aria-selected="true"] {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .08);
}

@media (prefers-color-scheme: dark) {
  .qz-home-tab[aria-selected="true"] {
    background: var(--surface-2);
    box-shadow: none;
  }
}

.qz-home-panel,
.qz-solve-home {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.qz-round-selector {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
}

.qz-round-selector__label {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}

.qz-round-selector__options {
  display: flex;
  flex: 1 1 auto;
  gap: 6px;
}

.qz-round-selector__option {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  padding: 8px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.qz-round-selector__option[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}

.qz-round-selector__option:disabled {
  opacity: .45;
  cursor: default;
}

/* 「全ての復習」タブ。周回セレクタと同じ系統で、直下に並んだときに
   ひと続きの選択肢に見えるようにする（変数経由なのでテーマは theme-dpg.css が正）。 */
.qz-all-review {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 4px;
}

.qz-all-review__label {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}

.qz-all-review__options {
  display: flex;
  flex: 1 1 auto;
  gap: 6px;
}

.qz-all-review__option {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;
  padding: 8px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 600;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.qz-all-review__option[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}

.qz-empty {
  text-align: center;
  color: var(--text-3);
  font-size: 14px;
  padding: 40px 20px;
}

/* --- buttons -------------------------------------------------------------------- */
.qz-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 10px 20px;
  border-radius: var(--r-md);
  font-size: 15px;
  font-weight: 600;
  transition: transform var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.qz-btn:active {
  transform: scale(.97);
}

.qz-btn:disabled {
  opacity: .4;
  cursor: default;
}

.qz-btn--block {
  width: 100%;
}

.qz-btn--primary {
  background: var(--accent);
  color: #fff;
}

.qz-btn--outline {
  background: var(--surface-2);
  color: var(--text);
}

.qz-btn--ghost {
  background: none;
  color: var(--text-2);
}

/* 元に戻せない操作だけに使う。塗りは薄い赤、文字だけを --danger にする。
   --danger をそのまま塗りにすると、白抜き文字が primary（青の塗り）と同じ
   重さになり、カードの中で一番強いボタンが「消す」になってしまう。 */
.qz-btn--danger {
  background: var(--danger-soft);
  color: var(--danger);
}

/* 同じ重みのボタンを横2連にする。全部を縦に積むと結果画面が7段になり、
   スクロールしないと「トップへ」に届かなくなる。
   gap も高さも .qz-btn の 44px 最小タップ領域は崩さない。 */
.qz-btn-row {
  display: flex;
  gap: 8px;
}

.qz-btn-row .qz-btn {
  flex: 1 1 0;
  min-width: 0;
}

/* 副になる側だけ幅を詰めて主/副の関係を見た目に出す。
   flex-basis ではなく flex-grow を落とすのは、ラベルが「絞る」の2文字でも
   タップ領域が細くなりすぎないようにするため。 */
.qz-btn-row .qz-btn--narrow {
  flex: 0 1 auto;
  min-width: 88px;
  padding-left: 16px;
  padding-right: 16px;
}

.qz-back {
  align-self: flex-start;
  font-size: 14px;
  color: var(--text-2);
  padding: 8px 4px;
}

/* --- set list (home) ------------------------------------------------------------ */
.qz-set-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qz-set-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qz-set-card__title {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

.qz-set-card__meta {
  font-size: 13px;
  color: var(--text-2);
}

/* progressLabel に周回名が入らない vm 用の小さな補助ラベル。本文より先に
   「今どの周か」を読むためのもので、単独カードを増やさない。 */
.qz-set-card__round {
  align-self: flex-start;
  margin-top: -2px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
}

/* ロックは disabled の開始ボタンでは表さない。押せない操作子を残すより、
   理由を本文として出す方がスクリーンリーダー/タッチ双方で明快。 */
.qz-set-card--locked {
  box-shadow: none;
}

.qz-set-card__locked {
  padding-top: 2px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
}

.qz-set-card__locked::before {
  content: "ロック中：";
  color: var(--text-3);
}

/* 間違いの件数。上の挑戦済み行と1つの塊に見せる（間にボタンが挟まって
   離れていたことが、隣に出ていた復習の進捗「0/4」を件数と読ませた原因）。 */
.qz-set-card__wrong {
  margin-top: -6px;
  font-size: 13px;
  color: var(--text-2);
}

/* 間違いの内訳。直下の「間違いN問を復習」ボタンの説明文なので、
   ボタンとの隙間を詰めて視覚的に1つの塊にする。 */
.qz-set-card__breakdown {
  margin-top: 2px;
  margin-bottom: -4px;
  font-size: 12px;
  color: var(--text-3);
}

/* 記録のリセット。1段目は目立たせない（探して初めて見つかるくらいでよい）。
   セパレータで上のボタン群と切るのは、押し間違いを距離ではなく境界で防ぐため。 */
.qz-set-card__reset {
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px solid var(--separator);
  font-size: 13px;
  color: var(--text-3);
}

/* 2段階目。qz-set-card 自体が gap:10px の縦 flex なので、ここも同じ骨格で並べる。 */
.qz-set-card__reset-armed {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 2px;
  padding-top: 12px;
  border-top: 1px solid var(--separator);
}

.qz-set-card__reset-note {
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-2);
}

/* 問題未登録のセット。押せる要素が無いことを彩度で伝える（枠だけ残す）。 */
.qz-set-card--empty {
  gap: 6px;
  box-shadow: none;
  border: 1px dashed var(--separator);
  background: transparent;
}

.qz-set-card--empty .qz-set-card__title {
  color: var(--text-2);
}

.qz-set-card--empty .qz-set-card__meta {
  color: var(--text-3);
}

/* --- setup ------------------------------------------------------------------------ */
.qz-page__title {
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  padding: 0 4px;
}

.qz-setup {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.qz-setup__group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qz-setup__label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}

.qz-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.qz-pill {
  min-height: 44px;
  padding: 8px 16px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 14px;
  transition: background var(--dur) var(--ease-out),
    color var(--dur) var(--ease-out);
}

.qz-pill[data-selected="true"] {
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 600;
}

/* 説明文。橙（--warn）から地の文の色へ落とす。説明も警告も同じ橙だと、
   色が「これは破壊的だ」という信号として機能しなくなる。 */
.qz-setup__note {
  font-size: 13px;
  color: var(--text-2);
}

/* 押すと何かが消えるときだけ出す行。橙はこちらが独占する。 */
.qz-setup__warn {
  font-size: 13px;
  color: var(--warn);
  font-weight: 600;
}

/* --- practice home ----------------------------------------------------------- */
.qz-practice-home {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.qz-practice-home__head {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* 中断状態と直近結果はメイン設定の前後に線で区切る。内側に別カードを重ねず、
   可読性だけを足す。 */
.qz-practice-home__session,
.qz-practice-home__recent {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 16px;
  border-top: 1px solid var(--separator);
}

.qz-practice-home__session {
  padding-top: 0;
  border-top: none;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--separator);
}

.qz-practice-home__subhead {
  font-size: 14px;
  font-weight: 700;
}

.qz-practice-home__session-label,
.qz-practice-home__detail {
  font-size: 13px;
  color: var(--text-2);
}

.qz-practice-home__disabled {
  font-size: 13px;
  color: var(--warn);
}

.qz-practice-range__controls {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: end;
  gap: 8px;
}

.qz-practice-range__controls--single {
  grid-template-columns: minmax(0, 1fr);
}

.qz-practice-range__field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.qz-practice-range__field-label,
.qz-practice-range__separator,
.qz-practice-range__summary {
  font-size: 12px;
  color: var(--text-3);
}

.qz-practice-range__separator {
  min-height: 44px;
  display: flex;
  align-items: center;
  padding-bottom: 1px;
}

.qz-practice-range__select {
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border: 1px solid var(--separator);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text);
  font: inherit;
  font-size: 16px; /* iOS Safari のフォーカス時ズームを防ぐ */
}

.qz-practice-range__summary {
  margin-top: -2px;
}

/* --- quiz head / progress --------------------------------------------------------- */
.qz-quiz-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 4px 0;
}

.qz-quiz-head__title {
  font-size: 15px;
  font-weight: 600;
  color: var(--text-2);
}

.qz-exit-btn {
  font-size: 13px;
  color: var(--text-2);
  padding: 8px 4px;
}

/* 見出しを伸ばして、🔊 と「トップへ」を右端へ寄せる。
   3つを space-between のままにすると 🔊 が中央に浮いて、押す対象に見えない。 */
.qz-quiz-head__title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 出題中の効果音トグル。押せることは分かるが、選択肢より目立ってはいけない。 */
.qz-sound-btn {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  margin-right: 2px;
  border: none;
  border-radius: var(--r-pill);
  background: transparent;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.qz-sound-btn:hover { background: var(--surface-2); }

/* 切っているときは沈める。絵文字の 🔇 だけだと、暗い画面では
   🔊 との差がスラッシュ1本しかなく、遠目に区別が付かない。 */
.qz-sound-btn[data-on="false"] { opacity: .45; }

.qz-sound-btn:disabled {
  opacity: .25;
  cursor: default;
}

.qz-progress-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 4px;
}

.qz-progress-label {
  font-size: 13px;
  color: var(--text-2);
}

.qz-progress-bar {
  height: 6px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  overflow: hidden;
}

.qz-progress-bar__fill {
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  transition: width var(--dur-slow) var(--ease-out);
}

@media (prefers-color-scheme: dark) {
  .qz-progress-bar__fill {
    background: var(--accent);
    opacity: .5;
  }
}

/* 進捗の文言・コンボ・リーチを1行に並べる。.qz-progress-row 自体は縦積みなので、
   ここで横並びの箱を1枚挟む（挟まないとバッジが行ごとに落ちて縦に伸びる）。 */
.qz-progress-row__head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}

/* コンボ。数字が主役なので、地は薄く・文字は主色のままにする。 */
.qz-combo {
  padding: 2px 10px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .06em;
}

/* リーチ。ゆっくり脈打たせる（0.8Hz ＝ 3Hz 規制の1/3以下）。
   明暗の反転ではなく不透明度と拡大だけで、光過敏の閾値に近づけない。 */
.qz-reach {
  padding: 2px 10px;
  border-radius: var(--r-pill);
  background: var(--danger-soft);
  color: var(--danger);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .12em;
  animation: qz-reach-pulse 1200ms var(--ease-out) infinite;
}

@keyframes qz-reach-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: .74; transform: scale(1.06); }
}

/* リーチ中は進捗バーも同じ色へ寄せる。バッジ1個だけだと、視線が問題文に
   ある間は最後まで気づかれない。 */
.qz-progress-row.is-reach .qz-progress-bar__fill {
  background: var(--danger-soft);
}

/* ★ 動きを止める設定では脈動そのものを消す ★ 全体の prefers-reduced-motion
   ルール（ファイル末尾）は「0.001ms で終了状態へ飛ばす」だけなので、
   infinite のアニメでは 0.001ms ごとに終端へ飛び続ける形が残りうる。
   ここで明示的に none にして、静止した状態を確定させる。 */
@media (prefers-reduced-motion: reduce) {
  .qz-reach {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* --- question card ------------------------------------------------------------------ */
.qz-question {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.qz-question__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 13px;
  color: var(--text-2);
}

.qz-question__no {
  color: var(--text-3);
}

.qz-type-badge {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-2);
  background: var(--surface-2);
  padding: 3px 9px;
  border-radius: var(--r-pill);
}

/* 図を挟むと本文が複数段落になる（実データは1問あたり最大4段落＋図8枚）。
   全部を 600 にすると太字の壁になって読み進められないので、地の文は 400 にする。
   設問そのもの（「〜はどれでしょうか。」）は必ず最後の段落に来るので、そこだけ
   600 に戻して視線の着地点を作る。段落が1つだけの従来形式の問題は、その1段落が
   :last-of-type にも該当するので今までどおり 600 のまま変わらない。
   figure の中の <p>（キャプション・404文言）は子孫であって兄弟ではないため、
   :last-of-type の数え上げには入らない。 */
.qz-question__stem {
  font-size: 17px;
  font-weight: 400;
  line-height: 1.6;
  white-space: pre-line;
}

.qz-question__stem:last-of-type {
  font-weight: 600;
}

/* --- choices -------------------------------------------------------------------------- */
.qz-choices {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qz-choice {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 12px 16px;
  border-radius: var(--r-md);
  border: 1.5px solid var(--separator);
  background: var(--surface);
  text-align: left;
  font-size: 15px;
  transition: background var(--dur) var(--ease-out),
    border-color var(--dur) var(--ease-out),
    opacity var(--dur) var(--ease-out);
}

.qz-choice:disabled {
  cursor: default;
}

.qz-choice__text {
  flex: 1 1 auto;
  min-width: 0;
  line-height: 1.4;
}

.qz-choice__icon {
  flex: 0 0 auto;
  font-weight: 700;
  font-size: 16px;
}

.qz-choice__status {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.qz-choice--correct {
  background: var(--success-soft);
  border-color: var(--success);
}

.qz-choice--correct .qz-choice__icon {
  color: var(--success);
}

.qz-choice--wrong {
  background: var(--danger-soft);
  border-color: var(--danger);
}

.qz-choice--wrong .qz-choice__icon {
  color: var(--danger);
}

.qz-choice--dim {
  opacity: .5;
}

.qz-choice--selected {
  border-color: var(--accent);
  background: var(--accent-soft);
}

.qz-choice--selected .qz-choice__icon {
  color: var(--accent);
}

/* 選択肢の直下に出る判定行。時間切れ・わからないでは正解の肢が緑になるだけで
   赤が1つも出ないため、肢の色だけでは正解したようにしか見えない。
   ★ 色は必ず CSS 変数で書くこと ★ theme-dpg.css は変数を差し替えるだけなので、
   固定色を書くとテーマ切替とダークモードで浮く。 */
.qz-verdict {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 9px 12px;
  border-radius: var(--r-md);
  font-size: 13px;
  font-weight: 700;
  line-height: 1.4;
  /* 文字は本文色。--danger を --danger-soft の上に直接置くとライトの両テーマで
     3.8〜4.2:1 しか出ず、13px の本文としては AA（4.5:1）に届かない
     （.qz-choice__status が本文色なのと同じ理由）。意味の色は縁とアイコンで出す。 */
  color: var(--text);
  border-left: 3px solid transparent;
}

.qz-verdict--correct {
  background: var(--success-soft);
  border-left-color: var(--success);
}

.qz-verdict--correct .qz-verdict__icon { color: var(--success); }

.qz-verdict--wrong,
.qz-verdict--dontknow,
.qz-verdict--timeout {
  background: var(--danger-soft);
  border-left-color: var(--danger);
}

.qz-verdict--wrong .qz-verdict__icon,
.qz-verdict--dontknow .qz-verdict__icon,
.qz-verdict--timeout .qz-verdict__icon { color: var(--danger); }

.qz-verdict__icon {
  flex: 0 0 auto;
  font-size: 15px;
}

/* --- explain / beginner cards ------------------------------------------------------------ */
.qz-explain,
.qz-beginner {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qz-explain__head,
.qz-beginner__head {
  font-size: 15px;
  font-weight: 700;
}

/* 「解説」見出しと解答時間を1行に並べる。時間は右端の控えめなチップにする
   （左に置くと見出しより先に目に入り、解説を読む前に数字が気になる）。 */
.qz-explain__headrow {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}

.qz-explain__time {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-3);
  background: var(--surface-2);
  border-radius: var(--r-pill);
  padding: 2px 10px;
}

@media (prefers-color-scheme: dark) {
  .qz-explain__time {
    background: var(--surface);
  }
}

/* 解説は「読ませる文章」なので、問題文(17px)・選択肢(15px)から落としすぎない。
   14px / text-2 では設問より2段弱く、本人から「解説の文字が見づらい」と出た
   （2026-09-16）。選択肢と同じ 15px・本文色まで戻し、行間だけ広めに取る。 */
.qz-explain__body,
.qz-beginner__lead {
  font-size: 15px;
  line-height: 1.75;
  color: var(--text);
  white-space: pre-line;
}

.qz-beginner {
  background: var(--surface-2);
}

@media (prefers-color-scheme: dark) {
  .qz-beginner {
    background: var(--surface);
  }
}

.qz-beginner__list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  list-style: none;
}

.qz-beginner__item {
  padding-top: 10px;
  border-top: 1px solid var(--separator);
}

.qz-beginner__row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
}

.qz-beginner__mark {
  flex: 0 0 auto;
  color: var(--danger);
  font-weight: 700;
}

.qz-beginner__reason {
  margin-top: 4px;
  margin-left: 24px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-2);
  white-space: pre-line;
}

/* 解説カード先頭（見出しの直下）のコピー欄。★ このアプリの中に AI は入れない ★
   外部チャットへ貼り付けるための文面と図を渡すだけの帯なので、解説本文の上に
   区切り線を1本引いて「解説の続きではない」ことを見た目でも分ける。
   ★ 線は下（border-bottom）★ 帯が上に来た以上、上に引くと見出しと本文の
   両方に線が挟まって、どちらの区切りか読めなくなる。
   390px 幅ではボタンが折り返す（flex-wrap）。横に詰めて字を小さくしない。 */
.qz-share {
  margin: 0 0 12px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--separator);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qz-share__row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* .qz-btn--outline が土台。幅は内容に合わせ、狭い画面では折り返させる。
   border を透明で先に敷いておくのは、成功／失敗のとき border-color だけを
   差し替えてもレイアウトが動かないようにするため。 */
.qz-share__btn {
  flex: 1 1 auto;
  min-height: 44px;   /* 他のボタン・歯車・止めるボタンと同じタップ目標 */
  font-size: 13px;
  border: 1.5px solid transparent;
}

.qz-share__btn[data-state="done"] {
  border-color: var(--success);
  color: var(--success);
}

.qz-share__btn[data-state="fail"] {
  border-color: var(--danger);
  color: var(--danger);
}

.qz-share__hint,
.qz-share__note {
  color: var(--text-2);
  font-size: 12px;
  line-height: 1.5;
  margin: 0;
}

/* --- practice study ---------------------------------------------------------- */
/* .qz-practice-question は通常の .qz-question を再利用し、選択肢だけを置かない。
   ここでは本文と解説に視線を集めるため、追加の装飾カードは作らない。 */
.qz-practice-question {
  gap: 12px;
}

.qz-practice-study__time {
  align-self: flex-end;
  margin-top: -6px;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-3);
  font-size: 12px;
}

@media (prefers-color-scheme: dark) {
  .qz-practice-study__time {
    background: var(--surface);
  }
}

/* --- result: score hero ---------------------------------------------------------------- */
.qz-result-hero {
  text-align: center;
  padding: 28px 20px 24px;
}

.qz-result-hero__label {
  font-size: 13px;
  color: var(--text-2);
  margin-bottom: 6px;
}

.qz-result-hero__score {
  font-size: clamp(44px, 12vw, 64px);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.qz-result-hero__slash {
  color: var(--text-3);
  font-weight: 400;
  margin: 0 4px;
}

.qz-result-hero__pct {
  margin-top: 6px;
  font-size: 15px;
  color: var(--text-2);
}

/* 所要時間はスコアより一段弱い。正答率と並べて「速いが不正解」を読み取らせる情報で、
   それ自体が主役ではない。区切り線を1本入れて数字の塊と分ける。 */
.qz-result-hero__time {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--separator);
  font-size: 14px;
  color: var(--text-2);
}

.qz-result-hero__slowest {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-3);
}

/* ニアミス（あと1問で満点）。スコアの直下に1行だけ。カードにしないのは、
   スコアと切り離れた瞬間に「別の情報」に見えて、惜しさが伝わらないため。
   ★ 色で強さを出さない ★ 13px の文字に --warn を敷くと地とのコントラストが
   AA を割る（.qz-miss-badge と同じ判断）。地色と太字だけで強める。 */
.qz-result__nearmiss {
  margin: -4px 4px 0;
  padding: 8px 14px;
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 13px;
  font-weight: 700;
  text-align: center;
}

.qz-complete,
.qz-review-summary {
  text-align: center;
}

.qz-complete__head {
  font-size: 20px;
  font-weight: 700;
  margin-bottom: 8px;
}

.qz-complete__body,
.qz-review-summary__body {
  font-size: 15px;
  color: var(--text-2);
}

/* --- result: wrong list ------------------------------------------------------------------ */
.qz-wrong-list__head {
  font-size: 15px;
  font-weight: 700;
  margin-bottom: 10px;
}

.qz-wrong-list__ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qz-wrong-list__item {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--separator);
}

.qz-wrong-list__item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.qz-wrong-list__no {
  flex: 0 0 auto;
  color: var(--text-3);
  font-size: 13px;
}

.qz-wrong-list__preview {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--text-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 「2回目」バッジ。色分けはしない — 12px の文字色でコントラストAAを保てる
   danger 系の色が無く、赤系にすると本文より目立つのに読みにくいという最悪の組合せに
   なる。地色（警告の淡色）と太字で強さを表す。 */
.qz-miss-badge {
  flex: 0 0 auto;
  font-size: 11px;
  font-weight: 700;
  color: var(--text-2);
  background: var(--surface-2);
  border-radius: var(--r-pill);
  padding: 2px 8px;
}

@media (prefers-color-scheme: dark) {
  .qz-miss-badge {
    background: var(--surface-2);
    color: var(--text);
  }
}

/* --- result actions ------------------------------------------------------------------------ */
.qz-result-actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* 「このブロックの操作」と「間違い全体の操作」の境目。
   線1本で、押した結果がブロック単位かセット単位かを区別させる。 */
.qz-result-actions__sep {
  height: 1px;
  background: var(--separator);
  margin: 4px 0;
}

/* 区切り線の直下に出る間違いの件数。ホームカードの同じ1行（.qz-set-card__wrong）と
   文字の大きさ・色を揃える。あちらの負のマージンは付けない（挑戦済み行とくっつける
   ためのもので、ここでは区切り線と重なる）。 */
.qz-result-actions__wrong {
  font-size: 13px;
  color: var(--text-2);
}

/* 結果画面に置くピル群は setup 画面と違ってカードの外に出るので、
   ラベルの余白だけ詰める（カード内の .qz-setup__group と同じ見た目にはしない）。 */
.qz-result-actions .qz-setup__group {
  gap: 6px;
}

/* --- practice result --------------------------------------------------------- */
.qz-practice-result__summary,
.qz-practice-result__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.qz-practice-result__head,
.qz-practice-result__list-head {
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* 3つの合計は同じ視線の高さに置く。画面幅が狭くても最小幅を持つので、
   数字だけが不自然に改行されない。 */
.qz-practice-totals {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.qz-practice-totals__item {
  min-width: 0;
  padding: 10px 8px;
  border-radius: var(--r-sm);
  background: var(--surface-2);
  text-align: center;
}

.qz-practice-totals__label {
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
}

.qz-practice-totals__value {
  margin-top: 2px;
  font-size: 14px;
  font-weight: 700;
  color: var(--text);
  white-space: nowrap;
}

.qz-practice-result__ul {
  display: flex;
  flex-direction: column;
  list-style: none;
}

.qz-practice-result__item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 0;
  border-bottom: 1px solid var(--separator);
}

.qz-practice-result__item:first-child {
  padding-top: 0;
}

.qz-practice-result__item:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

.qz-practice-result__row {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}

.qz-practice-result__no {
  flex: 0 0 auto;
  color: var(--text-3);
  font-size: 12px;
}

.qz-practice-result__preview {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 14px;
}

.qz-practice-result__status {
  flex: 0 0 auto;
  font-size: 12px;
  font-weight: 700;
}

.qz-practice-result__status--ok {
  color: var(--success);
}

.qz-practice-result__status--ng {
  color: var(--danger);
}

.qz-practice-result__times {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 10px;
  padding-left: 30px;
  font-size: 12px;
  color: var(--text-2);
}

/* --- figure（本文・解説・前文に挟まる表のスクリーンショット） ------------------------------------ */
.qz-figure {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

/* 画像そのものをタップターゲットにする。表の中身は縮むと読めないので、
   インラインは「ここに表がある」ことを示すサムネイルに徹し、読むのは
   タップで開く原寸ビューア（.qz-lightbox）側に任せる。 */
.qz-figure__btn {
  display: block;
  width: 100%;
  padding: 0;
  border-radius: var(--r-sm);
}

/* アスペクト比が最大12:1あり、素直に縮めると高さ25pxの帯になって押せない。
   min-height でタップ領域を確保し、余った分は contain で letterbox する。
   透過PNGが34枚あるので地を敷かないとダークモードで黒地に溶ける。 */
.qz-figure__img {
  display: block;
  width: 100%;
  height: auto;
  min-height: 44px;
  object-fit: contain;
  object-position: left top;
  background: #fff;
  border: 1px solid var(--separator);
  border-radius: var(--r-sm);
}

.qz-figure__cap {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-3);
}

/* 404 のときだけ出す。views.js の onerror は data-broken を立てるだけで
   （setState を呼ぶと再描画→再読込→再エラーの無限ループになる）、
   見た目の切り替えはこの2ルールに寄せている。 */
.qz-figure__fallback {
  display: none;
}

.qz-figure[data-broken="1"] .qz-figure__btn,
.qz-figure[data-broken="1"] .qz-figure__cap {
  display: none;
}

.qz-figure[data-broken="1"] .qz-figure__fallback {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 14px 12px;
  border: 1px dashed var(--separator);
  border-radius: var(--r-sm);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-3);
  overflow-wrap: anywhere;
}

/* 原因（＝読み手が最初に知りたいこと）を本文と同じ強さで出す。
   以前はファイル名だけを出していたので、読んだ人は必ずデータの欠損を疑いに行った。
   実際に多いのは認証切れで、正しい次の一手は「再読み込み」。 */
.qz-figure__fallback-lead {
  color: var(--text-2);
}

.qz-figure__fallback-act {
  color: var(--accent);
  font-weight: 600;
}

/* ファイル名は本当に欠けているときだけ意味を持つ情報なので、一段弱くする。 */
.qz-figure__fallback-src {
  font-size: 11px;
  color: var(--text-3);
}

/* ★ 画像に filter を掛けない ★ 以前はダークモードのときだけ
   brightness(.86) contrast(1.04) を掛けていた（真っ黒な背景では白地の表が眩しい、
   という理由）。ドパガキのテーマ（theme-dpg.css）は OS がダークでも常に紙色の
   明るい配色を出すので、眩しさの前提そのものが無くなった。残っていると、
   OSをダークにしている人にだけ、貼り付けた画像が原本より14%暗く見える。 */

/* --- lightbox（原寸ビューア） ----------------------------------------------------------------- */
/* buildQuiz が返す唯一のノード。display:contents なので .qz-page の
   レイアウト（flex column / gap）には一切影響しない。 */
.qz-root {
  display: contents;
}

/* body にクラスを足して背面をロックする代わりに、はみ出したスクロールをここで止める
   （app.js が #app の外を触らないという分担を崩さないため）。 */
.qz-lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: rgba(0, 0, 0, .92);
  overscroll-behavior: contain;
  padding:
    calc(env(safe-area-inset-top) + 8px) calc(env(safe-area-inset-right) + 8px)
    calc(env(safe-area-inset-bottom) + 8px) calc(env(safe-area-inset-left) + 8px);
}

.qz-lightbox__close {
  flex: 0 0 auto;
  align-self: flex-end;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, .14);
  color: #fff;
  font-size: 17px;
  line-height: 1;
}

.qz-lightbox__scroll {
  flex: 1 1 auto;
  overflow: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* max-width:none で原寸のまま出す（縮めたら拡大表示の意味が無い）。
   はみ出した分は __scroll の横スクロールで読む。 */
.qz-lightbox__img {
  display: block;
  max-width: none;
  background: #fff;
  border-radius: var(--r-sm);
}

.qz-lightbox__hint {
  flex: 0 0 auto;
  text-align: center;
  font-size: 12px;
  color: rgba(255, 255, 255, .62);
}

/* --- references（解説カード末尾の参照リンク） --------------------------------------------------- */
.qz-refs {
  padding-top: 12px;
  border-top: 1px solid var(--separator);
}

.qz-refs__head {
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
  margin-bottom: 6px;
}

.qz-refs__ul {
  list-style: none;
  display: flex;
  flex-direction: column;
}

/* 1本1本が44pxの独立したタップターゲットなので、境界線で押し間違いを防ぐ。
   最後の1本だけ線を落とすのは .qz-wrong-list__item と同じ扱い。 */
.qz-refs__item {
  border-bottom: 1px solid var(--separator);
}

.qz-refs__item:last-child {
  border-bottom: none;
}

.qz-refs__link {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 44px;
  padding: 6px 0;
  text-decoration: none;
  /* URLやタイトルに折り返せない長い連続文字が混じるのでカードから溢れさせない。 */
  overflow-wrap: anywhere;
}

.qz-refs__text {
  font-size: 14px;
  line-height: 1.5;
  color: var(--accent);
}

.qz-refs__host {
  font-size: 11px;
  letter-spacing: 0.02em;
  color: var(--text-3);
}

/* --- case study（7問共通のシナリオ前文） -------------------------------------------------------- */
.qz-case {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 8px 20px;
}

.qz-case__toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 56px;
  text-align: left;
}

.qz-case__title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.4;
}

.qz-case__meta {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-3);
}

.qz-case__chev {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--text-3);
}

/* 約4,300字＝スマホで11画面ぶん。素で流すと選択肢が画面外へ消えるので、
   カード内で高さを切って中だけスクロールさせる。トグルは箱の外なので、
   どこまで読んでも1タップで閉じられる。
   dvh は使わない（この codebase のトークンに無く、file:// の古い Safari で無視される）。 */
.qz-case__body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-height: 58vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px 0 16px;
  border-top: 1px solid var(--separator);
}

.qz-case__text {
  font-size: 14px;
  line-height: 1.7;
  color: var(--text-2);
  white-space: pre-line;
  /* 前文の末尾に原文（Google ドキュメント）の長い URL がリンクとして入る。
     折り返せないと .qz-case__body（overflow: auto）に横スクロールが出る。 */
  overflow-wrap: anywhere;
}

/* --- Gist 同期（フッタ） ------------------------------------------------------------------------
   クラス名を .sync / .sync__* / .footer__btn にしているのは、描画するのが
   assets/sync.js（ダッシュボードと共有のエンジン）で、そこが出すクラス名が
   固定だから。トークン名はダッシュボードの styles.css と同一なので、
   値ではなく変数を参照している限りライト/ダーク両方が自動で揃う。 */
.qz-foot {
  max-width: 720px;
  margin: 0 auto;
  padding: 8px 20px 24px;
  /* iPhone のホームインジケータに潜り込ませない（viewport-fit=cover のため） */
  padding-bottom: calc(24px + env(safe-area-inset-bottom, 0px));
}

.sync {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
}

.sync__status {
  font-size: 12px;
  color: var(--text-3);
}

.sync__status--error {
  color: var(--danger);
}

.sync__input {
  width: 100%;
  max-width: 320px;
  font-size: 16px; /* 16px 未満だと iOS Safari がフォーカス時にズームする */
  padding: 8px 10px;
  border-radius: var(--r-sm);
  border: 1px solid var(--separator);
  background: var(--surface-2);
  color: var(--text);
}

.sync__actions {
  display: flex;
  gap: 12px;
}

.sync__help,
.sync__error {
  width: 100%;
  max-width: 320px;
  font-size: 11px;
  text-align: center;
  margin: 0;
  color: var(--text-3);
}

.sync__error {
  color: var(--danger);
}

.footer__btn {
  font-size: 13px;
  color: var(--text-3);
  padding: 6px 4px;
  border-radius: var(--r-sm);
  background: none;
  border: none;
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}

.footer__btn:hover {
  color: var(--accent);
}

.footer__btn:disabled {
  opacity: .5;
  cursor: default;
}

/* --- countdown（制限時間） ---------------------------------------------------------------------
   進捗バーのすぐ下に置く。★ここは app.js が setState を介さず直接書き換える★
   毎秒 setState すると render() が画面全体を作り直し、選択肢と <img> が
   毎秒破棄・再生成される（タップ取りこぼし・画像の再取得）。
   だから CSS 側は「width と data-level が外から書き換わる」前提で組んである。
   ------------------------------------------------------------------------------------------- */
/* ★ スクロールしても上部に固定する（AZ104_Ver2.0 での変更）★
   ケーススタディと解説は画面数枚分あり、読んでいる間ずっと残り時間が視界の外に
   出ていた（＝時間切れが不意打ちになる）。
   ★ .qz-page（と祖先）に overflow を付けないこと ★ 付けた瞬間 sticky が死ぬ。
   .qz-page は flex 縦積みで overflow を持たず、.qz-app も持たないので
   sticky がそのまま効く。★ top は 0 にしない ★ sticky の top は body の
   padding と無関係に viewport の上端から測るので、viewport-fit=cover の
   iPhone では 0 だとノッチ／ステータスバーの下に潜って読めなくなる。
   left/right いっぱいに広げてヘッダー風の帯にするため、負のマージンで
   ページ左右の余白（--pad-page）ぶんはみ出し、同じ量を padding で戻す。
   浮いた分だけ本文がバーの裏を通るので、背景は半透明＋blur にして
   下の文字が透けて見えないようにする。 */
.qz-countdown {
  position: sticky;
  top: env(safe-area-inset-top, 0px);
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 calc(-1 * var(--pad-page));
  padding: 8px var(--pad-page);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--separator);
}

.qz-countdown__bar {
  flex: 1;
  height: 4px;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  overflow: hidden;
}

/* transition は付けない。200ms ごとに width を書き換えるので、
   遷移を挟むと常に「追いつく途中」の値が見えて、残りとバーがずれる。 */
.qz-countdown__fill {
  height: 100%;
  border-radius: var(--r-pill);
  background: var(--text-3);
  transform-origin: left center;
}

/* 折り返させない。幅 390px で「残り 1:00」が2行になると、
   バーの高さが毎秒変わってページ全体が跳ねる。 */
.qz-countdown__num {
  min-width: 3.2em;
  text-align: right;
  white-space: nowrap;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--text-2);
}

.qz-countdown[data-level="warn"] .qz-countdown__fill { background: var(--warn); }
.qz-countdown[data-level="warn"] .qz-countdown__num { color: var(--warn); }

.qz-countdown[data-level="danger"] .qz-countdown__fill { background: var(--danger); }

.qz-countdown[data-level="danger"] .qz-countdown__num {
  color: var(--danger);
  font-weight: 600;
  /* 1秒に1回だけ。速い明滅は光過敏性の観点で避ける（毎秒3回を超えさせない）。 */
  animation: qz-countdown-pulse 1s var(--ease-out) infinite;
}

@keyframes qz-countdown-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: .45; }
}

/* --- 「わからない」 -----------------------------------------------------------------------------
   ★ question.choices には足さない ★
   足すと answerIndex / answerIndices / beginner.wrong の添字が全部ずれ、
   buildBeginnerWrongList が正解肢を誤答欄に出す。独立したボタンとして選択肢の下に置く。
   見た目も選択肢と揃えない（選択肢の1つに見えると、4択が5択に読める）。
   ------------------------------------------------------------------------------------------- */
.qz-dontknow {
  width: 100%;
  padding: 11px 14px;
  border: 1px dashed var(--separator);
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text-2);
  font-size: 14px;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out),
    color var(--dur-fast) var(--ease-out);
}

.qz-dontknow:hover {
  background: var(--surface-2);
  color: var(--text);
}

.qz-dontknow:active { transform: scale(.99); }

/* --- 設定パネル ------------------------------------------------------------------------------ */
.qz-header__gear {
  position: absolute;
  top: 0;
  right: 0;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  color: var(--text-2);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-out);
}

.qz-header__gear:hover { background: var(--separator); }
.qz-header__gear[aria-expanded="true"] { background: var(--accent-soft); color: var(--accent); }

.qz-header { position: relative; }

.qz-settings {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 16px;
}

.qz-settings__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.qz-settings__label {
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
}

.qz-settings__note {
  font-size: 12px;
  line-height: 1.45;
  color: var(--text-2);
}

.qz-settings__group { display: flex; flex-direction: column; gap: 8px; }

/* iOS 風スイッチ。DESIGN.md のセグメントコントロールと同じく transform で動かす。 */
.qz-toggle {
  flex: 0 0 auto;
  width: 50px;
  height: 30px;
  padding: 0;
  border: none;
  border-radius: var(--r-pill);
  background: var(--surface-2);
  cursor: pointer;
  position: relative;
  transition: background var(--dur) var(--ease-out);
}

.qz-toggle::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .2);
  transition: transform var(--dur) var(--ease-out);
}

.qz-toggle[aria-pressed="true"] { background: var(--success); }
.qz-toggle[aria-pressed="true"]::after { transform: translateX(20px); }

.qz-toggle:disabled { opacity: .4; cursor: default; }

/* --- 全問正解の演出（パチンコ風） ---------------------------------------------------------------
   ★ このオーバーレイは #app の外（document.body 直下）に載る★
     中に置くと render() の root.textContent = "" で演出の途中に消える。
   金 = そのブロックが満点 / 虹 = セッション・練習を丸ごと満点（虹＝確定の作法）。
   ------------------------------------------------------------------------------------------- */
.qz-fanfare {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border: none;
  background: rgba(8, 4, 0, .82);
  cursor: pointer;
  animation: qz-fanfare-in 220ms var(--ease-out) both;
}

.qz-fanfare--out { animation: qz-fanfare-out 320ms var(--ease-out) both; }

@keyframes qz-fanfare-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes qz-fanfare-out { from { opacity: 1; } to { opacity: 0; } }

/* 放射バースト。連続回転は固定点で3回/秒を超える明暗反転になり得るため使わない。
   ビューポート等倍の静止レイヤー＋一度きりのフェードで、GPU負荷も抑える。 */
.qz-fanfare__burst {
  position: absolute;
  inset: 0;
  background:
    repeating-conic-gradient(from 0deg,
      rgba(255, 214, 102, .72) 0deg 2.6deg,
      rgba(255, 150, 30, 0) 2.6deg 18deg);
  -webkit-mask-image: radial-gradient(circle at center,
      #000 0, rgba(0, 0, 0, .78) 34vmin, transparent 78vmin);
  mask-image: radial-gradient(circle at center,
      #000 0, rgba(0, 0, 0, .78) 34vmin, transparent 78vmin);
  opacity: .78;
  animation: qz-fanfare-burst-in 620ms var(--ease-out) both;
}

.qz-fanfare--rainbow .qz-fanfare__burst {
  background:
    repeating-conic-gradient(from 0deg,
      rgba(255, 120, 150, .95) 0deg 3.2deg, rgba(255, 120, 150, 0) 3.2deg 9deg),
    repeating-conic-gradient(from 4.5deg,
      rgba(150, 225, 255, .92) 0deg 3.2deg, rgba(150, 225, 255, 0) 3.2deg 9deg),
    conic-gradient(from 0deg,
      #ff3b30, #ff9f0a, #ffd60a, #34c759, #0a84ff, #5e5ce6, #ff2d95, #ff3b30);
  opacity: .68;
}

@keyframes qz-fanfare-burst-in {
  from { opacity: .18; }
  to { opacity: .78; }
}

/* プレミア（金のうち確率で昇格した回）。金の変種で、赤みを一段足すだけにする。
   ★ 色は既存トークンと rgba だけで作る ★ ここへ新しい16進を足すと、テーマ側
   （theme-dpg.css）で上書きできない色がオーバーレイにだけ残る。
   ★ 明滅は作らない ★ 追加するのは1回きりのフェードと、見出しの入れ替え1回だけ
   （3回/秒以上の点滅を1つも増やさない）。 */
.qz-fanfare--premium { background: rgba(26, 2, 2, .86); }

.qz-fanfare--premium .qz-fanfare__burst {
  background:
    repeating-conic-gradient(from 0deg,
      rgba(255, 214, 102, .8) 0deg 2.6deg,
      rgba(255, 90, 40, 0) 2.6deg 14deg);
  opacity: .8;
}

/* 差し替え画像を指定したときは、CSS の放射をやめて画像1枚に任せる。 */
.qz-fanfare__burst--asset {
  background-image:
    var(--qz-fx-burst-image),
    repeating-conic-gradient(from 0deg,
      rgba(255, 214, 102, .64) 0deg 2.6deg,
      rgba(255, 150, 30, 0) 2.6deg 18deg);
  background-size: cover, auto;
  background-position: center;
  background-repeat: no-repeat;
}

.qz-fanfare__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}

/* 縦長の完成動画は、デスクトップでも上下を切らず1枚の演出盤として見せる。 */
.qz-fanfare__video--contain { object-fit: contain; }

/* 動画の実再生時刻が結果パネルへ届くまで見出しアニメを0フレームで停止する。
   再生失敗時はfallbackクラスで即時解放し、CSS＋HTMLだけでも意味を残す。 */
.qz-fanfare--video-pending .qz-fanfare__title { animation-play-state: paused; }

.qz-fanfare--video-pending.qz-fanfare--video-title-ready .qz-fanfare__title,
.qz-fanfare--video-pending.qz-fanfare--video-fallback .qz-fanfare__title {
  animation-delay: 0ms;
  animation-play-state: running;
}

/* 開始待ちが1秒を超えたときだけ、見出しを薄く出す（fanfare.js の
   VIDEO_WAITING_HINT_MS）。動画の開始は最大3秒待つので、その間まっ暗なままだと
   待っているのか壊れたのか区別がつかない。解放（title-ready）とは別物で、
   こちらは「まだ待っている」ことだけを見せる。
   ★ 薄くするのは __plate 側 ★ __title は qz-fanfare-pop が opacity を持つので、
     アニメーションの値が常に勝って opacity 宣言が効かない。
   ★ :not(--video-title-ready) が要 ★ waiting クラスは外さない（smoke の
     classList シムに remove が無い）。付けっぱなしのまま解放すると、
     本来くっきり出るはずの見出しが .55 のまま残る。 */
.qz-fanfare--video-pending.qz-fanfare--video-waiting:not(.qz-fanfare--video-title-ready) .qz-fanfare__title {
  animation-play-state: running;
}

.qz-fanfare--video-pending.qz-fanfare--video-waiting:not(.qz-fanfare--video-title-ready) .qz-fanfare__plate {
  opacity: .55;
}

/* 動画が終わっても閉じない（fanfare.js は ended で dismiss しない）。非ループなので
   video 要素は最後のコマで静止し、その上に達成見出しが乗ったまま残る。
   .qz-fanfare--video-ended はその状態を外から読むためのフックで、静止画としては
   これ以上手を入れる必要が無いため、あえて宣言を持たせていない。 */

.qz-fanfare--video-contained .qz-fanfare__stage::before,
.qz-fanfare--video-contained .qz-fanfare__stage::after {
  display: none;
}

.qz-fanfare--video-contained .qz-fanfare__title {
  font-size: clamp(48px, 12vmin, 88px);
}

/* 稲妻。stroke-dashoffset で描く（DESIGN.md のチェックマークと同じ手法）。 */
.qz-fanfare__bolts {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.qz-fanfare__bolt {
  fill: none;
  stroke: #fff6c9;
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 120;
  stroke-dashoffset: 120;
  filter: drop-shadow(0 0 3px rgba(255, 220, 120, .95));
  animation: qz-fanfare-bolt 700ms var(--ease-out) both;
}

@keyframes qz-fanfare-bolt {
  0% { stroke-dashoffset: 120; opacity: 0; }
  30% { opacity: 1; }
  100% { stroke-dashoffset: 0; opacity: .85; }
}

/* 火花。角度と距離は JS が CSS 変数で渡す（動きは CSS が持つ）。 */
.qz-fanfare__sparks {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  pointer-events: none;
}

.qz-fanfare__spark {
  position: absolute;
  width: var(--size, 6px);
  height: var(--size, 6px);
  margin: calc(var(--size, 6px) / -2) 0 0 calc(var(--size, 6px) / -2);
  border-radius: 50%;
  background: #fff3c4;
  box-shadow: 0 0 10px 2px rgba(255, 205, 90, .9);
  transform: rotate(var(--a, 0deg)) translateX(0);
  animation: qz-fanfare-spark 1100ms var(--ease-out) var(--delay, 0ms) both;
}

@keyframes qz-fanfare-spark {
  0% { transform: rotate(var(--a, 0deg)) translateX(0) scale(.4); opacity: 0; }
  18% { opacity: 1; }
  100% { transform: rotate(var(--a, 0deg)) translateX(var(--d, 40vmin)) scale(.2); opacity: 0; }
}

.qz-fanfare__stage {
  position: relative;
  z-index: 2;
  padding: 0 6vw;
  text-align: center;
  animation: qz-fanfare-stage-in 440ms var(--ease-spring) 80ms both;
}

/* 文字の後ろだけ暗く落とす。これが無いと、放射の明るい帯と金の文字が同じ明度で
   重なって輪郭が消える（実機で確認済み）。 */
.qz-fanfare__stage::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 150vmin;
  height: 110vmin;
  transform: translate(-50%, -50%);
  background: radial-gradient(ellipse at center,
      rgba(30, 12, 0, .92) 0%, rgba(24, 10, 0, .72) 38%, rgba(10, 4, 0, 0) 70%);
  z-index: -1;
  pointer-events: none;
}

/* 読める中央印を0.94倍から1回だけ着地させる。揺れ・ループは使わない。 */
@keyframes qz-fanfare-stage-in {
  from { transform: scale(.94); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

.qz-fanfare__plate {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.qz-fanfare__plate-img {
  max-width: min(70vw, 620px);
  max-height: 24vh;
  height: auto;
  object-fit: contain;
  animation: qz-fanfare-pop 520ms var(--ease-spring) both;
}

.qz-fanfare__badge {
  display: inline-block;
  padding: 5px 16px;
  border-radius: var(--r-pill);
  background: linear-gradient(180deg, #fff3c0, #f0b429);
  color: #4a2f04;
  font-size: 14px;
  font-weight: 800;
  letter-spacing: .18em;
  text-indent: .18em;
  box-shadow: 0 2px 10px rgba(255, 190, 60, .55);
  animation: qz-fanfare-pop 420ms var(--ease-spring) both;
}

.qz-fanfare--rainbow .qz-fanfare__badge {
  border: 2px solid transparent;
  background:
    linear-gradient(#171a24, #171a24) padding-box,
    linear-gradient(90deg, #ff3b30, #ffd60a, #34c759, #0a84ff, #ff2d95) border-box;
  color: #fff;
  text-shadow: none;
  box-shadow: 0 2px 14px rgba(126, 104, 255, .55);
}

/* 金／クロームの文字。
   ★ -webkit-text-stroke と background-clip:text は同じ要素で両立しない
     （縁取りが塗りの上へ乗って文字が潰れる）。だから縁取りは ::before の
     専用レイヤーに逃がし、本体は塗りだけを担当する。 */
.qz-fanfare__title {
  position: relative;
  display: inline-block;
  font-size: clamp(54px, 19vw, 132px);
  font-weight: 900;
  line-height: 1.04;
  letter-spacing: .02em;
  background: linear-gradient(180deg,
      #fffbe8 0%, #ffe9a3 18%, #f5c344 40%,
      #a9700f 52%, #ffe07a 60%, #f0b02c 80%, #7c4c06 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
  /* ★ paint-order: stroke fill が要（Safari 11+ / Chrome 116+）★
     これが無いと縁取りが塗りの上へ乗る。「全問正解」は画数が多く、
     7px の縁取り同士が字の内側で溶けて、文字全体が黒い塊になる（実機で確認済み）。
     stroke を先に塗れば、縁は字の外側にだけ残って読める。
     ::before に縁取り専用の層を敷く手もあるが、負の z-index は親の背景
     （＝background-clip:text で切り抜いた金グラデ）より後ろへ回るので、
     層が増えるだけで同じ問題が残る。 */
  -webkit-text-stroke: clamp(3px, .75vmin, 7px) #24160a;
  paint-order: stroke fill;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, .6));
  animation: qz-fanfare-pop 560ms var(--ease-spring) 60ms both;
}

.qz-fanfare--rainbow .qz-fanfare__title {
  background: linear-gradient(180deg,
      #ffffff 0%, #ffd0e8 14%, #ff8ad0 28%, #9b7bff 44%,
      #57c8ff 58%, #5ce6a6 72%, #ffe066 86%, #ff7a59 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* プレミアの見出しは金より赤い。トークンだけで作るので、テーマを替えれば
   一緒に動く（縁取りと paint-order は上の共通宣言をそのまま使う）。 */
.qz-fanfare--premium .qz-fanfare__title {
  background: linear-gradient(180deg,
      var(--warn) 0%, var(--danger) 52%, var(--warn) 100%);
  -webkit-background-clip: text;
  background-clip: text;
}

/* 2段目（「激アツ」→「プレミア」）へ入れ替えた瞬間だけ、もう一度跳ねさせる。
   文字だけ差し替わると、演出ではなく描画の事故に見える。 */
.qz-fanfare--premium-confirmed .qz-fanfare__title {
  animation: qz-fanfare-pop 420ms var(--ease-spring) both;
}

/* 動画に達成語が焼き込んである納品物（manifest の videoHasTitle）では、
   HTML の見出しを視覚的にだけ伏せる。読み上げからは外さない
   （aria-labelledby がこの見出しを指しているので、消すと名前の無い dialog になる）。
   ★ 動画が失敗した回は自動で元へ戻る ★ fanfare.js は付けたクラスを外さない
   （smoke の classList シムに remove が無い）ので、fallback クラスとの
   組み合わせでこの規則の方を外す。 */
.qz-fanfare--video-has-title.qz-fanfare--has-video:not(.qz-fanfare--video-fallback) .qz-fanfare__plate {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.qz-fanfare__sub {
  font-size: clamp(15px, 4.6vw, 22px);
  font-weight: 700;
  letter-spacing: .1em;
  color: #ffe9ae;
  text-shadow: 0 2px 10px #000, 0 0 24px rgba(0, 0, 0, .9);
  animation: qz-fanfare-pop 520ms var(--ease-spring) 160ms both;
}

.qz-fanfare--rainbow .qz-fanfare__sub { color: #fff; }

@keyframes qz-fanfare-pop {
  from { transform: scale(.42); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* 演出は自動で消えないので、このボタンが唯一の「終わらせ方」の表示になる。
   明るい動画のフレームに重なっても読めるよう、下地と枠を薄くしすぎない。 */
.qz-fanfare__close {
  position: absolute;
  left: 50%;
  bottom: max(28px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  z-index: 3;
  padding: 10px 26px;
  border: 1px solid rgba(255, 255, 255, .58);
  border-radius: var(--r-pill);
  background: rgba(0, 0, 0, .62);
  box-shadow: 0 2px 12px rgba(0, 0, 0, .45);
  color: #fff;
  font-size: 14px;
  cursor: pointer;
  animation: qz-fanfare-in 300ms var(--ease-out) 420ms both;
}

.qz-fanfare__close:hover { background: rgba(0, 0, 0, .78); }

/* reduce のときは静止画にする。全体の prefers-reduced-motion ルールでも
   アニメは止まるが、そちらは「終了状態へ飛ばす」だけなので、回転や揺れの
   最終状態が意図と違う層をここで明示的に殺しておく。 */
.qz-fanfare--still .qz-fanfare__burst { animation: none; }
.qz-fanfare--still .qz-fanfare__stage { animation: none; }

.qz-fanfare--still .qz-fanfare__title,
.qz-fanfare--still .qz-fanfare__badge,
.qz-fanfare--still .qz-fanfare__sub,
.qz-fanfare--still .qz-fanfare__plate-img {
  animation: none;
  transform: none;
  opacity: 1;
}

/* Windows の強制カラーモードでは透明なグラデーション文字が消えるため、
   演出の意味を担う3要素をシステム色の通常文字へ戻す。 */
@media (forced-colors: active) {
  .qz-fanfare__title,
  .qz-fanfare--rainbow .qz-fanfare__title,
  .qz-fanfare__sub,
  .qz-fanfare--rainbow .qz-fanfare__sub {
    background: none;
    color: CanvasText;
    -webkit-text-fill-color: CanvasText;
    -webkit-text-stroke: 0;
    filter: none;
    text-shadow: none;
  }

  .qz-fanfare__badge,
  .qz-fanfare--rainbow .qz-fanfare__badge,
  .qz-fanfare__close {
    border: 2px solid ButtonText;
    background: ButtonFace;
    color: ButtonText;
    box-shadow: none;
    text-shadow: none;
  }
}

/* --- reduced motion --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}


/* --- 本棚（作成・残り枠・購入シート・デッキ操作） ------------------------------- */
.qz-library {
  gap: 10px;
}

.qz-library__row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.qz-library__quota {
  padding: 4px 10px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
}

.qz-library__usage {
  font-size: 12px;
  line-height: 1.5;
  color: var(--warn);
}

.qz-library__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}

/* 文中リンク風のボタン。カードの主役（青い塗り）を増やさないための控えめな導線。 */
.qz-link {
  background: none;
  padding: 6px 0;
  min-height: 32px;
  font-size: 13px;
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.qz-link--danger {
  color: var(--danger);
}

.qz-purchase {
  gap: 10px;
}

.qz-purchase__title {
  font-size: 17px;
  font-weight: 700;
}

.qz-purchase__lead,
.qz-purchase__note {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text-2);
}

.qz-purchase__note {
  font-size: 12px;
  color: var(--text-3);
}

.qz-purchase__consent {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 13px;
  line-height: 1.5;
}

.qz-purchase__consent input {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
}

.qz-purchase__plans {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.qz-purchase__plan {
  flex-direction: column;
  gap: 2px;
  min-height: 60px;
  padding: 8px 6px;
}

.qz-purchase__plan-label {
  font-size: 13px;
}

.qz-purchase__price {
  font-size: 16px;
  font-weight: 800;
}

@media (max-width: 420px) {
  .qz-purchase__plans {
    grid-template-columns: minmax(0, 1fr);
  }
}

.qz-set-card__actions {
  display: flex;
  gap: 16px;
  margin-top: -4px;
}

.qz-set-card__license {
  font-size: 11px;
  line-height: 1.5;
  color: var(--text-3);
}

.qz-set-card__delete {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.qz-set-card__delete-note {
  font-size: 13px;
  line-height: 1.5;
  color: var(--danger);
}


/* --- 法務フッタ（#app の外・ETS 免責と規約への導線） ---------------------------- */
.qz-foot--legal {
  max-width: var(--maxw);
  margin: 24px auto 0;
  padding: 16px var(--pad-page) 32px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  color: var(--text-3);
  font-size: 11px;
  line-height: 1.6;
}

.qz-foot__links {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}

.qz-foot__links a {
  color: var(--text-2);
  font-size: 12px;
  text-decoration: underline;
  text-underline-offset: 3px;
  padding: 6px 0;
}

/* 文字入力型の穴埋め。既存テーマの文字色・背景色を継承する。 */
.qz-cloze-form { display: grid; gap: 12px; }
.qz-cloze-form label { display: grid; gap: 8px; }
.qz-cloze-input { box-sizing: border-box; width: 100%; min-width: 0; padding: 12px; font: inherit; color: inherit; background: var(--paper, #fcfbf9); border: 1px solid currentColor; border-radius: 6px; }
.qz-cloze-form p, .qz-cloze-result p { overflow-wrap: anywhere; }
.qz-cloze-input:focus-visible { outline: 3px solid currentColor; outline-offset: 3px; }

.qz-book-cover { display: block; width: 100%; aspect-ratio: 16 / 5; object-fit: cover; border-radius: 10px; margin-bottom: 16px; }

/* --- AI解説メモ（外部AIの回答を1問ごとに貯める欄） ------------------------------
   解説より前（上の「次へ」の直下）に置くカード。上から「画像 → 文章」。
   ボタンは .qz-btn ＋ .qz-share__btn をそのまま使う（flashButton が書き換える
   data-state の見た目を1箇所に保つため、ここで独自のボタンを作らない）。 */
.qz-notes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.qz-notes__head {
  font-size: 15px;
  font-weight: 700;
  color: var(--text);
}

/* 読み取りに失敗した／クリップボードを読めなかったときの一行。role="status" が
   付くのはこの要素だけなので、見た目も本文と混ざらないようにする。 */
.qz-notes__status {
  font-size: 13px;
  line-height: 1.5;
  color: var(--danger);
}

.qz-notes__images {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.qz-notes__image {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 貼り付け先。clipboard.read() を拒否される端末ではここへフォーカスして
   長押し／Ctrl+V する。中身は常に空（views 側が beforeinput を飲む）なので、
   案内文は ::before で描く＝ユーザーが消せるテキストを置かない。 */
.qz-notes__drop {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 8px 12px;
  border: 1.5px dashed var(--separator);
  border-radius: var(--r-sm);
  background: var(--surface-2);
  color: var(--text-3);
  font-size: 13px;
  line-height: 1.5;
  text-align: center;
  /* 文字は入らないので、点滅するキャレットは出さない（入力欄と誤解される）。 */
  caret-color: transparent;
}

.qz-notes__drop::before {
  content: "ここを長押し／Ctrl+V で画像を貼り付け";
}

.qz-notes__drop:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-color-scheme: dark) {
  .qz-notes__drop {
    background: var(--surface);
  }
}

@media (forced-colors: active) {
  .qz-notes__drop {
    border-color: ButtonText;
    color: CanvasText;
  }
}

/* 本文は解説（.qz-explain__body）と同じ大きさ。中身は note-markdown.js で
   段落・見出し・箇条書きに割ってあるので、空白の保存（pre-wrap）はしない
   ＝余白は各ブロックの margin が作る。単独改行は views が <br> にする。
   長い URL や英単語はどこでも折る。 */
.qz-notes__body {
  font-size: 15px;
  line-height: 1.75;
  color: var(--text);
  white-space: normal;
  overflow-wrap: anywhere;
}

/* note-markdown.js が無い環境（旧 index.html）で落ちる素の1段落。
   割っていないので、ここだけは改行と空行を字面どおり残す。 */
.qz-notes__plain {
  white-space: pre-wrap;
}

/* --- 貼り付けた Markdown の見た目 ------------------------------------------------------ */
/* 見出しは h4/h5/h6（文書構造は本文の下の段）。大きさは 17/16/15px で、
   問題文と選択肢の間に収める＝解説の中だけで階層が分かればよい。 */
.qz-md__h {
  font-weight: 600;
  line-height: 1.5;
  margin: 14px 0 6px;
}

.qz-md__h--1 {
  font-size: 17px;
}

.qz-md__h--2 {
  font-size: 16px;
}

.qz-md__h--3 {
  font-size: 15px;
}

.qz-notes__body > :first-child {
  margin-top: 0;
}

.qz-md__p {
  margin: 0 0 10px;
}

.qz-md__list {
  padding-left: 1.4em;
  margin: 0 0 10px;
}

.qz-md__list li {
  margin: 4px 0;
}

.qz-md__list .qz-md__list {
  margin-top: 4px;
  margin-bottom: 0;
}

.qz-md__quote {
  margin: 0 0 10px;
  padding: 6px 12px;
  border-left: 3px solid var(--accent);
  background: var(--accent-soft);
  border-radius: var(--r-sm);
}

.qz-md__rule {
  border: 0;
  border-top: 1px solid var(--separator);
  margin: 12px 0;
}

/* 「↓」だけの行。AIが記憶の道筋を縦に並べるときの継ぎ目なので、
   本文と同じ強さで出すと行数だけが増えて読みが止まる。 */
.qz-md__arrow {
  margin: 2px 0;
  text-align: center;
  color: var(--text-3);
}

.qz-notes__body strong {
  color: var(--text);
  font-weight: 700;
}

.qz-md__code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .92em;
  padding: 1px 4px;
  background: var(--surface-2);
  border-radius: 4px;
}

.qz-notes__body--clamped {
  max-height: 14em;
  overflow: hidden;
  /* 下端をぼかして「まだ続きがある」ことを示す。切り落としの直線だと、
     そこで終わっているのか畳まれているのかが読めない。 */
  -webkit-mask-image: linear-gradient(180deg, #000 70%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 70%, transparent 100%);
}

.qz-notes__more {
  align-self: flex-start;
  padding-left: 0;
  padding-right: 0;
  font-size: 13px;
}

.qz-notes__empty {
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-3);
}

/* assets/editor.css は遅延読み込みでこの画面には来ないので、入力欄の値を写す。 */
.qz-notes__textarea {
  width: 100%;
  min-width: 0;
  min-height: 10em;
  padding: 10px 12px;
  border: 1px solid var(--separator);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 15px;
  line-height: 1.5;
  resize: vertical;
}

/* iOS Safari は 16px 未満の入力欄にフォーカスすると画面を勝手に拡大する
   （戻すのは手動。本人の常用環境が iPhone なのでここだけ大きくする）。 */
@media (max-width: 480px) {
  .qz-notes__textarea {
    font-size: 16px;
  }
}

.qz-notes__file {
  display: none;
}
