/* ============================================================
 * 19b. Toast / Feedback 浮层（v7.7 修复）
 *
 * 问题：v7.7 不加载 panels.css/decision-panels.css，
 *      feedback.js 通过 document.body.appendChild() 添加的 toast/feedback 元素
 *      在文档流中落到 grid 底部，玩家看不到。
 * 修复：6 个 feedback 类全部 position:fixed 浮层化，z-index 200+
 *
 * 涉及类（来自 src/ui/feedback.js）：
 *   .combo-toast            - combo 触发提示（1250ms 后自动消失）
 *   .match-feedback         - 进球/失球/失败大事件
 *   .energy-float           - 能量变化漂浮数字
 *   .reward-picked-flash    - 奖励选择闪光
 * ============================================================ */

/* ============================================================
 * Toast 统一定位系统（v1.2 路径 B 落地后整理）
 *
 * 问题：F 线时间线默认隐藏，旧两栏布局的宽屏偏移会让 toast 在常态下偏左。
 *
 * 方案：
 *   - 水平：所有 toast 锚定当前主内容中心。用 --toast-shift 变量，
 *           默认 = 0；宽屏且时间线打开 = -118px（右侧让位 236px 的一半）
 *   - 垂直分两层：
 *       L1 顶部条 (top: 24px)：高频轻量（出牌掷骰 / combo）
 *       L2 中上层 (top: 22%) ：戏剧化（进球失球大事件）
 *       同层多个 toast 互相替换（JS 已 remove before append）
 *
 *   energy-float / reward-picked-flash 维持原位（锚定具体元素或绝对居中场景）
 * ============================================================ */

:root {
  --toast-shift: 0px;
}

/* F 线宽屏：时间线打开时，主内容为右侧抽屉让出 236px。
 * toast 同步左移一半，仍对齐主内容中心。
 */
@media (min-width: 1024px) {
  body.timeline-open {
    --toast-shift: -118px;
  }
  body.timeline-open.timeline-wide {
    --toast-shift: -188px;
  }
}

/* L1 顶部条：高频轻量 */
.combo-toast {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translateX(calc(-50% + var(--toast-shift)));
  z-index: 200;
  background: var(--bg-panel);
  border: 1px solid var(--gold-primary);
  border-radius: 0;
  padding: 10px 18px;
  box-shadow: 5px 5px 0 rgba(229, 181, 103, 0.35);
  min-width: 220px;
  max-width: min(500px, 90vw);
  text-align: center;
  pointer-events: none;
  animation: v77-toast-in 0.25s ease-out both;
}

/* L1 顶部条：单牌出牌掷骰（与 combo 共用区域，互相替换）*/
.v77-hand-toast {
  position: fixed;
  top: 24px;
  left: 50%;
  transform: translateX(calc(-50% + var(--toast-shift)));
  z-index: 210;
  background: var(--bg-panel);
  border-radius: 0;
  padding: 8px 16px;
  min-width: 220px;
  max-width: min(440px, 90vw);
  text-align: center;
  pointer-events: none;
  animation: v77-toast-in 0.22s ease-out both;
  font-family: var(--font-mono);
}
.v77-hand-toast.ok {
  border: 1px solid var(--gold-primary);
  box-shadow: 5px 5px 0 rgba(229, 181, 103, 0.28);
}
.v77-hand-toast.fail {
  border: 1px solid #7a3a3a;
  box-shadow: 5px 5px 0 rgba(180, 60, 60, 0.22);
}
.v77-hand-toast b {
  display: block;
  font-size: 13px;
  font-weight: bold;
  letter-spacing: 0.4px;
}
.v77-hand-toast.ok b { color: var(--gold-primary); }
.v77-hand-toast.fail b { color: #d77a7a; }
.v77-hand-toast .v77-hand-toast-dice {
  display: block;
  font-size: 11px;
  color: var(--text-muted);
  margin-top: 2px;
  letter-spacing: 0.5px;
}

.combo-toast b {
  display: block;
  font-size: 14px;
  font-weight: bold;
  color: var(--gold-primary);
  margin-bottom: 2px;
  letter-spacing: 0.5px;
}

.combo-toast span {
  display: block;
  font-size: 12px;
  color: var(--text-main);
  line-height: 1.4;
}

/* L2 中上层：戏剧化大事件（进球 / 失球 / 大失败）*/
.match-feedback {
  position: fixed;
  top: 22%;
  left: 50%;
  transform: translateX(calc(-50% + var(--toast-shift)));
  z-index: 200;
  background: var(--bg-panel);
  border: 2px solid var(--border-default);
  border-radius: 0;
  padding: 18px 32px;
  box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.65);
  min-width: 280px;
  max-width: min(560px, 90vw);
  text-align: center;
  pointer-events: none;
  animation: v77-toast-in 0.3s ease-out both;
  animation-delay: 240ms;  /* 第 3 个出场（最戏剧化的，留到最后）*/
}

.match-feedback b {
  display: block;
  font-size: 24px;
  font-weight: bold;
  color: var(--text-primary);
  margin-bottom: 6px;
  letter-spacing: 1px;
}

.match-feedback span {
  display: block;
  font-size: 13px;
  color: var(--text-main);
  line-height: 1.4;
}

.match-feedback.goal {
  border-color: var(--green);
  box-shadow: 5px 5px 0 rgba(76, 175, 80, 0.5);
}

.match-feedback.goal b {
  color: var(--green);
}

.match-feedback.concede,
.match-feedback.fail {
  border-color: var(--red);
  box-shadow: 5px 5px 0 rgba(239, 83, 80, 0.45);
}

.match-feedback.concede b,
.match-feedback.fail b {
  color: var(--red);
}

/* v1.2 fallback 配色映射：让 warning / defend / success 与 goal / concede 视觉区分清晰
 * （combo fallback 已弃用 — reward / coach 改走专属 toast）
 */
.match-feedback.warning {
  border-color: var(--orange);
  box-shadow: 5px 5px 0 rgba(232, 160, 74, 0.42);
}
.match-feedback.warning b { color: var(--orange); }

.match-feedback.defend {
  border-color: var(--blue);
  box-shadow: 5px 5px 0 rgba(90, 160, 232, 0.40);
}
.match-feedback.defend b { color: var(--blue); }

/* success = "接近达成但未进球"，比 goal 弱半度（半透金，区别于实色绿）*/
.match-feedback.success {
  border-color: var(--gold-dim);
  box-shadow: 5px 5px 0 rgba(229, 181, 103, 0.32);
}
.match-feedback.success b { color: var(--gold-primary); }

.energy-float {
  position: fixed;
  z-index: 180;
  font-size: 18px;
  font-weight: bold;
  pointer-events: none;
  animation: v77-energy-float 0.9s ease-out forwards;
}

.energy-float.gain {
  color: var(--gold-primary);
}

.energy-float.spend {
  color: var(--red);
}

/* 奖励选择闪光：屏幕中心（场景需要全屏聚焦，跟 toast 分层不同）
 * --toast-y: -50% 让统一动画的 Y 中心保持 -50%（不被 translateY(0) 覆盖）
 */
.reward-picked-flash {
  --toast-y: -50%;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(calc(-50% + var(--toast-shift)), -50%);
  z-index: 200;
  background: var(--gold-primary);
  color: var(--bg-deepest);
  border-radius: 0;
  padding: 14px 28px;
  box-shadow: 5px 5px 0 rgba(229, 181, 103, 0.6);
  font-size: 14px;
  font-weight: bold;
  pointer-events: none;
  animation: v77-toast-in 0.25s ease-out both;
}

/* 粒子爆发（cards.js createParticleBurst） */
.play-burst {
  position: fixed;
  pointer-events: none;
  z-index: 160;
  width: 0;
  height: 0;
}

.play-burst i {
  position: absolute;
  left: -5px;
  top: -5px;
  width: var(--size, 8px);
  height: var(--size, 8px);
  background: var(--spark, var(--gold-primary));
  box-shadow: 0 0 0 var(--spark, var(--gold-primary));
  clip-path: polygon(50% 0, 62% 35%, 100% 35%, 69% 56%, 82% 100%, 50% 72%, 18% 100%, 31% 56%, 0 35%, 38% 35%);
  animation: v77-burst-fly 820ms cubic-bezier(.12, .78, .22, 1) forwards;
}

@keyframes v77-burst-fly {
  0%   { opacity: 1; transform: translate(0, 0) scale(0.42) rotate(0); }
  70%  { opacity: 0.9; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.08) rotate(260deg); }
}

/* 移动端 / 低性能设备减弱动画 */
@media (prefers-reduced-motion: reduce) {
  .play-burst i {
    animation: none;
  }
}

/* v1.2 统一 toast 动画：下出 → 停 → 上消失
 * keyframes 内 transform 必须包含 var(--toast-shift)，否则会覆盖元素自身的主列偏移，
 * 导致动画结束时 toast "跳回 body 中心" — 用户看到的就是"往左跑"的 bug 根因
 *
 * --toast-y：默认 0（顶部/中上锚定），reward-picked-flash 等中心锚定的覆盖为 -50%
 */
@keyframes v77-toast-in {
  from {
    opacity: 0;
    transform: translate(calc(-50% + var(--toast-shift)), calc(var(--toast-y, 0px) + 12px));
  }
  to {
    opacity: 1;
    transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px));
  }
}

/* Toast 退场：上消失（feedback.js 在 setTimeout 前加 .v77-toast-out class）
 *
 * 退场动画按 toast 的定位模型分组（关键：keyframes 的 transform 必须匹配元素
 * 自身的定位模型，否则会强行覆盖 → 元素瞬移到错位）：
 *
 *   组 A: 用 transform 居中 (-50% + --toast-shift)
 *         combo-toast / v77-hand-toast / match-feedback / reward-picked-flash
 *
 */
.combo-toast.v77-toast-out,
.v77-hand-toast.v77-toast-out,
.match-feedback.v77-toast-out,
.reward-picked-flash.v77-toast-out {
  animation: v77-toast-fade-out 0.32s cubic-bezier(.4, 0, .7, .3) forwards !important;
}

@keyframes v77-toast-fade-out {
  from {
    opacity: 1;
    transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px));
  }
  to {
    opacity: 0;
    transform: translate(calc(-50% + var(--toast-shift)), calc(var(--toast-y, 0px) - 14px));
  }
}

@keyframes v77-energy-float {
  0% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-30px); }
}

/* v1.2 整理：toast 主列偏移已由 --toast-shift 统一控制（参见上方 :root + @media），
 * 旧的 `left:` 覆盖规则已删除，避免与 transform 偏移冲突。
 */

/* a11y：尊重系统"减少动效"偏好（前庭功能障碍 / ADHD / 偏好极简）
 * 所有 toast 动画退化为纯淡入淡出，去掉位移；屏幕震动取消；脉冲呼吸取消
 * Steam / App Store / 平台审核合规项
 */
@media (prefers-reduced-motion: reduce) {
  @keyframes v77-toast-in {
    from { opacity: 0; transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px)); }
    to   { opacity: 1; transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px)); }
  }
  @keyframes v77-toast-fade-out {
    from { opacity: 1; transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px)); }
    to   { opacity: 0; transform: translate(calc(-50% + var(--toast-shift)), var(--toast-y, 0px)); }
  }
  @keyframes v77-energy-float {
    0% { opacity: 1; transform: translateY(0); }
    100% { opacity: 0; transform: translateY(0); }
  }
  /* 屏幕震动取消 */
  body.feedback-shake {
    animation: none !important;
  }
  /* 按钮脉冲呼吸取消 */
  #end-turn-btn.must-end {
    animation: none !important;
  }
}

/* body 屏幕震动效果（feedback.js 加 class）*/
body.feedback-shake {
  animation: v77-shake 0.46s;
}

@keyframes v77-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-4px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(3px); }
}

/* score 数字弹出动画 */
.feedback-score-pop {
  animation: v77-score-pop 0.6s ease-out;
}

@keyframes v77-score-pop {
  0% { transform: scale(1); }
  30% { transform: scale(1.3); color: var(--gold-primary); }
  100% { transform: scale(1); }
}
