/* 教程引擎样式
 * 容器策略：所有 UI 都 fixed 在 body 上，z-index 高于 Modal(6000) 让教程在弹窗打开时仍可见。
 * 气泡/任务条/退出按钮用 left:50% + transform 居中 + max-width 500px，确保在手机屏（含限宽 #app）内可见。
 * 透明遮罩 z-index 5000 低于 Modal，让 Modal 打开时用户能正常交互弹窗。
 *
 * box 与弹窗关系（动态分层，tutorial-engine _syncModalZAboveTutorialBox）：
 *   - 教程引导链上的弹窗（索引 < _guidedModalTopCount）：spotlight(9001)/引导圈(9002) 在弹窗(6002+) 之上。
 *   - 用户自发多开的弹窗（索引 >= _guidedModalTopCount）：临时抬到 9200+，盖过 bubble(9100)。
 */

.tutorial-hidden { display: none !important; }

/* 2026-06-04 宝宝原话「下拉层级还比不过引导框」根因：教程 4 ring 在 _freeGuideLayer (fixed z=9002)
   高于 #modal-container (z=6000) stacking context；modal 内的 settings-font-panel (absolute z=20)
   被 modal-container 6000 stacking 封装，物理 z 永远低于 ring 9002 → ring 边框盖过 panel 选项条目。
   修法：用 :has 选择 — 教程态 + 字体下拉打开时，临时整层 hide 4 ring（panel 操作完关回去后还原）。
   :has() Chrome 105+ 支持，宝宝主用 Chrome 没问题；其他 popup 类（颜色选择器 等）后续按需扩展。 */
body:has(#modal-container .modal-overlay:not([data-closing]) .settings-font-panel:not(.hidden)) .tutorial-free-guide-layer {
  display: none !important;
}

/* ========== 透明遮罩 - 接收外围点击 → 推进 ========== */
.tutorial-overlay {
  position: fixed;
  inset: 0;
  z-index: 5000;
  background: transparent;
  pointer-events: auto;
  cursor: pointer;
}

/* 开局媒体场景 = 借用真游戏引擎跑临时教程故事，DOM 由 GameEngine 接管，
 * 教程引擎只在媒体场景期间隐藏 overlay/bubble/spotlight，让玩家在真实游戏页面里推进。 */

/* spotlight 框住的目标元素：即便被 disabled / 半透明，视觉上强制清晰；
   disabled 状态本身保留防止玩家点错地方跳出教程 */
.tutorial-spotlight-target,
.tutorial-spotlight-target[disabled] {
  opacity: 1 !important;
}

/* ========== 镂空高亮 - box-shadow 形成视口黑遮罩 ========== */
/* spotlight 框住的范围：
 *   - 目标在 modal 外（顶栏 nav 按钮等） → spotlight 框住按钮本身
 *   - 目标在 modal 内（弹窗里的具体项目） → spotlight 框住整个 modal 容器，弹窗整体亮起来
 * 弹窗内具体目标交给 .tutorial-indicator 脉冲圈单独指示。 */
.tutorial-spotlight {
  position: fixed;
  border-radius: 8px;
  pointer-events: none;
  z-index: 9001;
  /* 主页面在教程进行时仍要清晰可见——黑罩仅用轻度压暗（0.28）让 spotlight 框醒目即可，
     不再吃掉主区可读性。彩色脉冲边框 + indicator 才是真正吸引视线的元素。 */
  box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.28);
  transition: top 0.18s ease, left 0.18s ease, width 0.18s ease, height 0.18s ease;
}

.tutorial-spotlight::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 2px solid var(--accent-color);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-color) 35%, transparent);
  animation: tutorial-pulse 1.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes tutorial-pulse {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(1.04); }
}

/* ========== 弹窗内目标的脉冲指示器 - 只显示边框圈，不做黑罩 ========== */
/* 弹窗整体被 spotlight 镂空亮起后，弹窗里具体要点的元素用这个圈再次强调位置。
 * z-index 比 modal-overlay(6001+) 高，比教程 bubble(9100) 低；不阻挡点击。 */
.tutorial-indicator {
  position: fixed;
  border-radius: 8px;
  pointer-events: none;
  z-index: 9002;
  border: 2px solid var(--accent-color);
  box-shadow:
    0 0 0 2px color-mix(in srgb, var(--accent-color) 30%, transparent),
    0 0 12px color-mix(in srgb, var(--accent-color) 45%, transparent);
  animation: tutorial-pulse 1.4s ease-in-out infinite;
  transition: top 0.18s ease, left 0.18s ease, width 0.18s ease, height 0.18s ease;
}

/* ========== 面包说话框（指导模式）========== */
/* 位置/大小由 JS 实时算 #app-scale-inner rect 来设置，永远在 #app 范围内 */
.tutorial-bubble {
  position: fixed;
  z-index: 9100;
  /* base 居中：动画结束后 transform 回到这里，避免气泡偏右出框 */
  transform: translateX(-50%);
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid color-mix(in srgb, var(--accent-color) 30%, var(--border-color));
  border-radius: 12px;
  /* padding-right 给右上角 close x（22x22@right:6) 留出 28px 留白防文字与按钮重叠 */
  padding: 10px 32px 12px 12px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5);
  display: flex;
  gap: 10px;
  font-size: var(--ui-fs-12);
  line-height: 1.55;
  pointer-events: none;
  box-sizing: border-box;
  animation: tutorial-bubble-in 0.28s ease-out;
}

@keyframes tutorial-bubble-in {
  from { transform: translateX(-50%) scale(0.92); opacity: 0; }
  to   { transform: translateX(-50%) scale(1); opacity: 1; }
}

.tutorial-bubble--has-actions { pointer-events: auto; }

/* readOnly 纯讲解 step（点任意位置推进）：box 自身轻微脉冲提示用户"可继续"，
   避免宝宝抱怨「导入自定义美化这里就被卡死了」=没继续按钮看着像卡死。
   不加任何文字（按规范不能 AI 编 UI 文案），只用视觉脉冲 + cursor:pointer 暗示。 */
.tutorial-bubble--tap-anywhere {
  cursor: pointer;
  pointer-events: auto;
  animation: tutorial-bubble-tap-pulse 1.6s ease-in-out infinite;
}

@keyframes tutorial-bubble-tap-pulse {
  0%, 100% {
    transform: translateX(-50%) scale(1);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5),
                0 0 0 0 color-mix(in srgb, var(--accent-color) 35%, transparent);
  }
  50% {
    transform: translateX(-50%) scale(1.015);
    box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5),
                0 0 0 6px color-mix(in srgb, var(--accent-color) 18%, transparent);
  }
}

.tutorial-bubble-avatar {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 2px solid color-mix(in srgb, var(--accent-color) 60%, transparent);
  overflow: hidden;
  background: var(--bg-tertiary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.tutorial-bubble-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

.tutorial-bubble-content {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.tutorial-bubble-name {
  font-size: var(--ui-fs-10);
  color: var(--accent-color);
  font-weight: 600;
  letter-spacing: 0.04em;
}

.tutorial-bubble-text {
  white-space: pre-wrap;
  word-break: break-word;
}

.tutorial-bubble-tap-hint {
  font-size: var(--ui-fs-10);
  color: var(--text-secondary);
  text-align: right;
  margin-top: 2px;
  animation: tutorial-tap-blink 1.4s ease-in-out infinite;
}

@keyframes tutorial-tap-blink {
  0%, 100% { opacity: 0.45; transform: translateY(0); }
  50%      { opacity: 1; transform: translateY(2px); }
}

.tutorial-bubble-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: 4px;
}

.tutorial-bubble-actions .btn { min-width: 76px; }

/* ========== 教程模式下的立绘：顶天立地（撑满高度，宽度允许溢出由容器裁切） ========== */
.game-media-layer.is-tutorial .game-media-character {
  /* 撑满容器高度；宽度按图比例算可能超出容器，由 game-media-layer 的 overflow 裁切 */
  max-height: 100%;
  height: 100%;
  max-width: none;
  /* 改 cover 让人物撑满整个画面，halfBody 图人物在中心，左右多余背景可被裁 */
  object-fit: cover;
  /* 锚在底中：人物脚部贴底、头部顶屏 */
  object-position: center top;
}

/* ========== 教程模式下的选项按钮：高对比度卡片，序号用 accent 色突出 ========== */
.game-media-layer.is-tutorial .choice-area .choice-btn {
  background: color-mix(in srgb, var(--accent-color) 10%, var(--bg-secondary));
  color: var(--text-primary);
  border: 1.5px solid color-mix(in srgb, var(--accent-color) 55%, var(--border-color));
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
  font-weight: 500;
}
.game-media-layer.is-tutorial .choice-area .choice-btn:active {
  background: color-mix(in srgb, var(--accent-color) 22%, var(--bg-secondary));
}
.game-media-layer.is-tutorial .choice-area .choice-btn b {
  color: var(--accent-color);
  font-weight: 800;
  font-size: 1.15em;
  margin-right: 0.2em;
}

/* ========== 关闭教程 x（挂在 box 右上角，跟 box 走，无论 box 在哪都能关）========== */
/* 宝宝原话「把关闭教程变成 x 放在哐哐面包的 box 上，这样无论在哪里都可以关」：
   x 作为 _bubble 的 absolute 子元素，跟着 box 一起渲染/隐藏/移动，不再独立 fixed 定位。
   _bubble 默认是 position:fixed 自带定位上下文，absolute x 直接按 _bubble 边界定位。 */
.tutorial-bubble-close {
  position: absolute;
  top: 4px;
  right: 6px;
  width: 22px;
  height: 22px;
  padding: 0;
  margin: 0;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--text-secondary);
  font-size: 18px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  pointer-events: auto;
  z-index: 1;
}
.tutorial-bubble-close:hover {
  color: var(--text-primary);
  background: color-mix(in srgb, var(--accent-color) 18%, transparent);
}
.tutorial-bubble-close:active {
  background: color-mix(in srgb, var(--accent-color) 28%, transparent);
}

