/* ==== 不正解エフェクト (画面フラッシュ + 「不正解！」テキスト) ==== */
        .wrong-flash-overlay {
          position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
          background: rgba(239, 68, 68, 0.28);
          pointer-events: none; z-index: 9998;
          animation: wrongFlash 0.6s ease-out forwards;
        }
        @keyframes wrongFlash {
          0% { opacity: 0; }
          25% { opacity: 1; }
          100% { opacity: 0; }
        }
        .wrong-stamp-effect {
          position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
          z-index: 9999; pointer-events: none; color: #ff4b4b; font-family: 'Arial Black', sans-serif;
          font-size: clamp(56px, 9vw, 116px); font-weight: 900; letter-spacing: 0.08em;
          text-shadow: 0 0 12px rgba(255, 75, 75, 0.95), 0 0 32px rgba(239, 68, 68, 0.7);
          animation: wrongStampPop 0.6s cubic-bezier(0.16, 1.2, 0.24, 1) forwards;
        }
        @keyframes wrongStampPop {
          0% { opacity: 0; transform: translate(-50%, -50%) scale(2.4) rotate(6deg); }
          25% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(-3deg); }
          85% { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(-3deg); }
          100% { opacity: 0; transform: translate(-50%, -50%) scale(0.9); }
        }

        /* ==== 「解説を聞く」ボタン (答え表示後にユーザーが押してパル解説を呼ぶ) ==== */
        .listen-explain-btn {
          position: fixed;
          left: 50%;
          bottom: 110px;
          transform: translate(-50%, 20px);
          padding: 16px 36px;
          font-family: inherit;
          font-size: 1.15rem;
          font-weight: 900;
          letter-spacing: 0.06em;
          color: #fff;
          background: linear-gradient(135deg, rgba(29, 78, 216, 0.95), rgba(14, 165, 233, 0.9));
          border: 2px solid rgba(125, 211, 252, 0.7);
          border-radius: 999px;
          cursor: pointer;
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(56, 189, 248, 0.5);
          opacity: 0;
          z-index: 3200;
          transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
          pointer-events: none;
          animation: listenExplainPulse 1.8s ease-in-out infinite;
        }
        .listen-explain-btn.show {
          opacity: 1;
          transform: translate(-50%, 0);
          pointer-events: auto;
        }
        .listen-explain-btn.hidden { display: none !important; }
        .listen-explain-btn:hover {
          background: linear-gradient(135deg, rgba(29, 78, 216, 1), rgba(14, 165, 233, 1));
          border-color: rgba(255, 255, 255, 0.9);
        }
        .listen-explain-arrow {
          display: inline-block;
          margin-left: 6px;
          transition: transform 0.2s ease;
        }
        .listen-explain-btn:hover .listen-explain-arrow {
          transform: translateX(4px);
        }
        @keyframes listenExplainPulse {
          0%, 100% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(56, 189, 248, 0.5); }
          50% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 56px rgba(56, 189, 248, 0.85); }
        }

        /* 答え表示中 (body.answer-reveal-locked): ワークスペースの操作を止める。
           ブロックを動かしたり削除したりできると、答え表示が崩れて解説の流れが壊れるため。
           ただしパンやズームは邪魔したくないので blocklyWorkspace ではなく draggable 要素だけ狙う */
        body.answer-reveal-locked .blocklyBlockCanvas,
        body.answer-reveal-locked .blocklyTrash,
        body.answer-reveal-locked .blocklyToolbox,
        body.answer-reveal-locked .blocklyFlyout {
          pointer-events: none !important;
        }

        /* 各種オーバーレイ画面 */
        .overlay-screen { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(2, 8, 20, 0.8); backdrop-filter: blur(12px); display: flex; justify-content: center; align-items: center; z-index: 2000; }
        
        /* 公式ブロック内の番号フィールドを太字＆少し大きく強調 */
        /* 「次のステージへ」独立ボタン (パル解説モード中に表示)
           listen-explain-btn と同じ丸型スタイルだが、位置を右下寄せに変えて
           下部アクションバー (リセット/あきらめる) と競合しないようにする */
        .listen-explain-btn.next-stage-btn {
          bottom: 40px;
          left: auto;
          right: 40px;
          transform: translate(20px, 0);
          background: linear-gradient(135deg, rgba(147, 51, 234, 0.95), rgba(126, 34, 206, 0.9));
          border-color: rgba(196, 181, 253, 0.7);
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(147, 51, 234, 0.5);
          animation: nextStagePulse 1.8s ease-in-out infinite;
        }
        .listen-explain-btn.next-stage-btn.show {
          transform: translate(0, 0);
        }
        .listen-explain-btn.next-stage-btn:hover {
          background: linear-gradient(135deg, rgba(147, 51, 234, 1), rgba(126, 34, 206, 1));
          border-color: rgba(255, 255, 255, 0.9);
        }
        @keyframes nextStagePulse {
          0%, 100% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(147, 51, 234, 0.5); }
          50% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 56px rgba(147, 51, 234, 0.85); }
        }
        /* ==== パル解説モード後の独立ボタングループ (もう一度 / 次の問題へ) ==== */
        .post-explain-button-group {
          position: fixed;
          bottom: 40px;
          left: 50%;
          transform: translate(-50%, 20px);
          display: flex;
          gap: 20px;
          z-index: 3200;
          opacity: 0;
          transition: opacity 0.35s ease, transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1);
          pointer-events: none;
        }
        .post-explain-button-group.show {
          opacity: 1;
          transform: translate(-50%, 0);
          pointer-events: auto;
        }
        .post-explain-button-group.hidden { display: none !important; }

        /* 解説パネルが出ている間は、このボタン群をパネルと同じ列に揃える。
           以前は常に画面下中央固定で、右ドックのパネルとバラバラの位置に出ていた。
           「読み終えたら押す」ボタンなので、視線の終点(パネル)の近くに置く。 */
        body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-btn {
          flex: 1;
          min-width: 0;
          white-space: nowrap;   /* 幅が足りないと縦書きに潰れるのを防ぐ */
          height: var(--reveal-btn-height, 56px);
          padding-top: 0;
          padding-bottom: 0;
        }
        /* 解説中は下部アクションバー(リセット/ヒント等)を隠す。
           answer-reveal-locked で全ボタンが無効化されており押せないので、
           出しておく意味がない。縦の余白が空いてパネルを大きく取れる。 */
        body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .action-bar-container {
          display: none;
        }

        /* 横長: 解説バンドと左右の端を揃えて、その真下に置く。
           バンドは中央寄せの最大 1800px なので、ボタン群も同じ計算で並べる。
           右寄せにすることで「読み終えたら右下へ」という視線の流れを作る。 */
        @media (min-aspect-ratio: 1/1) {
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-button-group {
            left: clamp(16px, 1.6vw, 40px);
            right: clamp(16px, 1.6vw, 40px);
            max-width: 1800px;
            margin-inline: auto;
            bottom: var(--reveal-btn-gap, 20px);
            transform: translateY(20px);
            justify-content: flex-end;
            gap: 14px;
          }
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-button-group.show {
            transform: translateY(0);
          }
          /* バンド下では横いっぱいに引き伸ばさず、内容なりの幅にする */
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-btn {
            flex: 0 0 auto;
            min-width: 200px;
          }
        }

        /* 縦長: 画面下いっぱいに 2 分割。シートはこの上に載る */
        @media (max-aspect-ratio: 1/1) {
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-button-group {
            left: clamp(8px, 2vw, 20px);
            right: clamp(8px, 2vw, 20px);
            bottom: var(--reveal-btn-gap, 20px);
            transform: translateY(20px);
            gap: 10px;
          }
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-button-group.show {
            transform: translateY(0);
          }
          body:has(.character-dialog-host.answer-reveal-mode:not(.hidden)) .post-explain-btn {
            padding: 12px 10px;
            font-size: clamp(0.8rem, 2.6vw, 0.95rem);
          }
        }

        .post-explain-btn {
          padding: 14px 32px;
          font-family: inherit;
          font-size: 1.05rem;
          font-weight: 900;
          letter-spacing: 0.05em;
          color: #ffffff;
          border-radius: 999px;
          cursor: pointer;
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
          transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
        }
        .post-explain-btn:hover {
          transform: translateY(-3px);
        }
        .post-explain-arrow {
          display: inline-block;
          font-weight: 900;
          transition: transform 0.2s ease;
        }

        /* もう一度 (左): 落ち着いた青系グラデーション、控えめ */
        .post-explain-btn.retry-btn {
          background: linear-gradient(135deg, rgba(51, 65, 85, 0.95), rgba(30, 41, 59, 0.9));
          border: 2px solid rgba(148, 163, 184, 0.55);
        }
        .post-explain-btn.retry-btn:hover {
          background: linear-gradient(135deg, rgba(71, 85, 105, 1), rgba(51, 65, 85, 1));
          border-color: rgba(203, 213, 225, 0.85);
        }
        .post-explain-btn.retry-btn .post-explain-arrow {
          margin-right: 6px;
        }
        .post-explain-btn.retry-btn:hover .post-explain-arrow {
          transform: rotate(-45deg);
        }

        /* 次の問題へ (右、デフォルト): 紫グラデーション、パルス発光で目立たせる */
        .post-explain-btn.next-stage-btn {
          background: linear-gradient(135deg, rgba(147, 51, 234, 0.95), rgba(126, 34, 206, 0.9));
          border: 2px solid rgba(196, 181, 253, 0.7);
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(147, 51, 234, 0.5);
          animation: postExplainNextPulse 1.8s ease-in-out infinite;
        }
        .post-explain-btn.next-stage-btn:hover {
          background: linear-gradient(135deg, rgba(147, 51, 234, 1), rgba(126, 34, 206, 1));
          border-color: rgba(255, 255, 255, 0.9);
        }
        .post-explain-btn.next-stage-btn:hover .post-explain-arrow {
          transform: translateX(4px);
        }
        @keyframes postExplainNextPulse {
          0%, 100% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(147, 51, 234, 0.5); }
          50% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 56px rgba(147, 51, 234, 0.85); }
        }

        /* 最終ステージ (「マップへ」): 水色系 */
        .post-explain-btn.next-stage-btn.final-stage {
          background: linear-gradient(135deg, rgba(56, 189, 248, 0.95), rgba(14, 116, 175, 0.9));
          border-color: rgba(125, 211, 252, 0.75);
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(56, 189, 248, 0.5);
          animation: postExplainFinalPulse 1.8s ease-in-out infinite;
        }
        .post-explain-btn.next-stage-btn.final-stage:hover {
          background: linear-gradient(135deg, rgba(56, 189, 248, 1), rgba(14, 116, 175, 1));
        }
        @keyframes postExplainFinalPulse {
          0%, 100% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 32px rgba(56, 189, 248, 0.5); }
          50% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 56px rgba(56, 189, 248, 0.85); }
        }

        /* 全問題クリア (「本編クリア！🎉」): 金色 */
        .post-explain-btn.next-stage-btn.all-cleared {
          background: linear-gradient(135deg, rgba(251, 191, 36, 0.98), rgba(217, 119, 6, 0.95));
          border-color: rgba(254, 240, 138, 0.9);
          color: #1f2937;
          font-size: 1.15rem;
          padding: 16px 36px;
          box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 48px rgba(251, 191, 36, 0.75);
          animation: postExplainAllClearedPulse 1.3s ease-in-out infinite;
        }
        .post-explain-btn.next-stage-btn.all-cleared:hover {
          background: linear-gradient(135deg, rgba(254, 215, 79, 1), rgba(245, 158, 11, 1));
          border-color: #ffffff;
          transform: translateY(-3px) scale(1.05);
        }
        @keyframes postExplainAllClearedPulse {
          0%, 100% { box-shadow: 0 12px 32px rgba(0, 0, 0, 0.55), 0 0 48px rgba(251, 191, 36, 0.75); }
          50% { box-shadow: 0 12px 36px rgba(0, 0, 0, 0.65), 0 0 80px rgba(254, 215, 79, 1); }
        }

/* ============================================================
   正解時エフェクト（波紋 + CLEAR! スタンプ）
   app-effects.js の showSuccessRipple() / showClearStamp() が生成する要素。
   クラス定義がどのCSSにも無く、正解しても画面に何も出ていなかったため追加。
   ============================================================ */
.success-ripple {
  position: fixed;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
  border-radius: 50%;
  border: 4px solid rgba(88, 204, 2, 0.9);
  background: radial-gradient(circle, rgba(88, 204, 2, 0.28), rgba(88, 204, 2, 0) 70%);
  box-shadow: 0 0 40px 10px rgba(88, 204, 2, 0.45);
  pointer-events: none;
  z-index: 12000;
  animation: successRippleExpand 1s ease-out forwards;
}
@keyframes successRippleExpand {
  0%   { transform: scale(0.2); opacity: 0.95; }
  70%  { opacity: 0.55; }
  100% { transform: scale(9);   opacity: 0; }
}

.clear-stamp-effect {
  position: fixed;
  top: 42%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.2) rotate(-16deg);
  font-family: inherit;
  font-weight: 900;
  font-size: clamp(48px, 11vw, 132px);
  letter-spacing: 0.06em;
  color: #eafff0;
  -webkit-text-stroke: 3px rgba(34, 197, 94, 0.95);
  text-shadow:
    0 0 18px rgba(88, 204, 2, 0.9),
    0 0 46px rgba(34, 197, 94, 0.65),
    0 12px 30px rgba(0, 0, 0, 0.5);
  pointer-events: none;
  white-space: nowrap;
  z-index: 12001;
  animation: clearStampSlam 1.5s cubic-bezier(0.18, 1.3, 0.4, 1) forwards;
}
@keyframes clearStampSlam {
  0%   { transform: translate(-50%, -50%) scale(2.6) rotate(-16deg); opacity: 0; }
  18%  { transform: translate(-50%, -50%) scale(0.92) rotate(-8deg); opacity: 1; }
  30%  { transform: translate(-50%, -50%) scale(1.06) rotate(-10deg); }
  42%  { transform: translate(-50%, -50%) scale(1) rotate(-9deg); }
  78%  { transform: translate(-50%, -50%) scale(1) rotate(-9deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(1.12) rotate(-9deg); opacity: 0; }
}

/* 連続正解カウンター（#streak-counter）。updateStreakCounter() が更新する。 */
#streak-counter {
  display: inline-block;
  min-width: 58px;
  padding: 6px 12px;
  border-radius: 999px;
  background: linear-gradient(135deg, rgba(245, 158, 11, 0.22), rgba(180, 83, 9, 0.18));
  border: 1px solid rgba(245, 158, 11, 0.45);
  color: #ffd79a;
  font-weight: 900;
  font-size: 14px;
  text-align: center;
  letter-spacing: 0.02em;
  text-shadow: 0 0 10px rgba(245, 158, 11, 0.6);
}
#streak-counter.streak-bounce { animation: streakBounce 0.5s cubic-bezier(0.2, 1.4, 0.4, 1); }
@keyframes streakBounce {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.35); }
  70%  { transform: scale(0.94); }
  100% { transform: scale(1); }
}

/* マップ上「あきらめて解説を見た」ノード（自力クリアとは見た目を分ける） */
.map-node.gave-up {
  border-color: rgba(148, 163, 184, 0.7) !important;
  filter: saturate(0.55);
}