/* ==========================================================================
   [CSS-4] 特效样式
   光晕扩散（3星卡级光环）、金色光柱（5星全屏）、屏幕闪光（5星）、
   结算星星点亮配合样式、按钮霓光
   （keyframes 定义统一在 animations.css）
   ========================================================================== */

/* ==========================================================================
   3星多层光晕环：由 stage.js 在触发时向卡片插入 .fx-rings，
   卡片获得 .is-halo 类后三环依次扩散
   ========================================================================== */
.fx-rings {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  aspect-ratio: 5 / 7;
  pointer-events: none;
  z-index: -1;
}

.fx-rings i {
  position: absolute;
  inset: -8%;
  border-radius: 50%;
  opacity: 0;
  border: 2px solid rgba(240, 212, 124, 0.9);
  box-shadow:
    0 0 24px rgba(212, 175, 55, 0.55),
    inset 0 0 24px rgba(212, 175, 55, 0.4);
}

.fx-rings i:nth-child(1) { border-width: 3px; }
.fx-rings i:nth-child(2) { border-color: rgba(255, 246, 216, 0.85); }
.fx-rings i:nth-child(3) {
  border-color: rgba(212, 175, 55, 0.7);
  border-style: dashed;
}

.gacha-card.is-halo .fx-rings i {
  animation: halo-burst 1.45s var(--ease-apple) 2 forwards;
}

.gacha-card.is-halo .fx-rings i:nth-child(2) { animation-delay: 0.22s; }
.gacha-card.is-halo .fx-rings i:nth-child(3) { animation-delay: 0.44s; }

/* 3星卡片本体辉光（演出窗口期间）
   ⚠️ 辉光绝不能加在 .card-inner（preserve-3d 层）上——filter 会强制打平
   3D 上下文，导致正反面判定反转（演出期间一直显示卡背）。
   也不能用 filter 加在 .card-face 上——filter 会创建渲染表面，卡面内
   扫光/流光动画每一帧都强制整个模糊表面重绘，实测掉帧"光卡在半路"。
   方案：box-shadow 金晕。box-shadow 既不创建渲染表面（模糊结果可缓存），
   也不是 grouping property（完全不触碰 3D 上下文），三重安全。 */
.gacha-card.is-halo.is-flipped .card-front {
  box-shadow:
    0 10px 26px rgba(196, 154, 49, 0.5),
    0 0 22px rgba(240, 212, 124, 0.9),
    0 0 44px rgba(240, 212, 124, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.7),
    inset 0 0 16px rgba(255, 248, 214, 0.55);
}

/* ==========================================================================
   5星全屏金色光柱：中央主柱 + 两侧斜柱（多柱并立的电影感）
   ========================================================================== */
.fx-beam {
  position: fixed;
  inset: 0;
  z-index: var(--z-beam);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.45s var(--ease-apple);
  overflow: hidden;
}

.fx-beam.is-active {
  opacity: 1;
}

.beam-core {
  position: absolute;
  left: 50%;
  top: -12%;
  width: min(40vw, 440px);
  height: 124%;
  transform: translateX(-50%);
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(250, 237, 196, 0.32) 18%,
    rgba(255, 248, 220, 0.7) 46%,
    rgba(250, 237, 196, 0.5) 68%,
    rgba(240, 212, 124, 0.22) 84%,
    transparent 100%);
  filter: blur(12px);
  mix-blend-mode: screen;
}

.fx-beam.is-active .beam-core {
  animation: beam-pulse 1.5s ease-in-out infinite;
}

.beam-side {
  position: absolute;
  top: -16%;
  width: min(11vw, 120px);
  height: 132%;
  background: linear-gradient(to bottom,
    transparent 0%,
    rgba(250, 237, 196, 0.4) 30%,
    rgba(255, 248, 220, 0.62) 58%,
    transparent 100%);
  filter: blur(8px);
  mix-blend-mode: screen;
}

.fx-beam.is-active .beam-side {
  animation: beam-side-pulse 1.5s ease-in-out infinite;
}

.beam-left {
  left: 16%;
  transform: rotate(9deg);
}

.beam-right {
  right: 16%;
  transform: rotate(-9deg);
}

/* ==========================================================================
   5星屏幕闪光：全屏白金光幕（stage.js 触发 is-flashing 重播）
   ========================================================================== */
.fx-flash {
  position: fixed;
  inset: 0;
  z-index: var(--z-flash);
  pointer-events: none;
  opacity: 0;
  background:
    radial-gradient(circle at 50% 62%, rgba(255, 253, 240, 0.98) 0%, rgba(255, 250, 224, 0.85) 38%, rgba(250, 237, 196, 0.4) 62%, transparent 82%);
}

.fx-flash.is-flashing {
  animation: flash-pop 0.9s var(--ease-apple) forwards;
}

/* ==========================================================================
   5星卡片专属：舞台级注目（粒子雨时光柱之外的卡片自身强调）
   同上：box-shadow 金晕，不用 filter（避免渲染表面拖垮流光动画帧率）
   ========================================================================== */
.gacha-card.is-cinematic.is-flipped .card-front {
  box-shadow:
    0 14px 34px rgba(150, 112, 24, 0.55),
    0 0 30px rgba(255, 246, 216, 0.95),
    0 0 64px rgba(240, 212, 124, 0.6),
    inset 0 0 20px rgba(255, 248, 214, 0.7);
}

/* ==========================================================================
   全屏粒子画布（fx.js 单实例持有）
   ========================================================================== */
.fx-canvas {
  position: fixed;
  inset: 0;
  z-index: var(--z-canvas);
  width: 100%;
  height: 100%;
  pointer-events: none;
}

/* ==========================================================================
   按钮霓光：主按钮呼吸金晕 + hover 提亮
   ========================================================================== */
.btn-primary:not(:disabled) {
  animation: btn-breath 2.8s ease-in-out infinite;
}

.btn-primary:not(:disabled):hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
}

/* ==========================================================================
   [Rev.7] 召唤过场：星夜暗场 + 金色彗星斜掠 + 撞击爆闪（原神祈愿感）
   stage.js 点击"抽卡"后置 .is-active，1.65s 演出结束后撤下
   ========================================================================== */
.fx-summon {
  position: fixed;
  inset: 0;
  z-index: var(--z-summon);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.4s var(--ease-apple);
  overflow: hidden;
}

.fx-summon.is-active {
  opacity: 1;
}

/* 星夜底：暖金沉入深空蓝的垂直渐变 */
.summon-sky {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(90vmax 60vmax at 50% 118%, rgba(122, 90, 36, 0.85), transparent 62%),
    linear-gradient(180deg, #17122E 0%, #2A2044 46%, #4A3620 100%);
}

/* 星屑：纯 CSS 多点星图，双层错尺寸闪烁 */
.summon-sky::before,
.summon-sky::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(1.6px 1.6px at 12% 22%, #FFF6D8, transparent),
    radial-gradient(1.2px 1.2px at 28% 64%, #FFFFFF, transparent),
    radial-gradient(1.8px 1.8px at 44% 14%, #F5D77E, transparent),
    radial-gradient(1.1px 1.1px at 58% 42%, #FFFFFF, transparent),
    radial-gradient(1.5px 1.5px at 71% 26%, #FFF6D8, transparent),
    radial-gradient(1.2px 1.2px at 84% 58%, #F5D77E, transparent),
    radial-gradient(1.4px 1.4px at 36% 82%, #FFFFFF, transparent),
    radial-gradient(1.1px 1.1px at 92% 12%, #FFF6D8, transparent);
  animation: starfield-twinkle 1.3s ease-in-out infinite;
}

.summon-sky::after {
  background-image:
    radial-gradient(1.2px 1.2px at 8% 48%, #FFFFFF, transparent),
    radial-gradient(1.5px 1.5px at 22% 8%, #FFF6D8, transparent),
    radial-gradient(1.1px 1.1px at 52% 74%, #F5D77E, transparent),
    radial-gradient(1.6px 1.6px at 66% 88%, #FFFFFF, transparent),
    radial-gradient(1.3px 1.3px at 78% 44%, #FFF6D8, transparent),
    radial-gradient(1.1px 1.1px at 90% 78%, #FFFFFF, transparent),
    radial-gradient(1.4px 1.4px at 48% 52%, #F5D77E, transparent);
  animation-delay: 0.65s;
}

/* 彗星：亮点头部 + 渐变长尾（尾巴朝向右上方来路） */
.summon-comet {
  position: absolute;
  left: 76%;
  top: 20%;
  width: 0;
  height: 0;
  opacity: 0;
}

.fx-summon.is-active .summon-comet {
  animation: comet-fly 1.06s cubic-bezier(0.45, 0.05, 0.7, 0.35) 0.06s forwards;
}

.comet-head {
  position: absolute;
  left: -7px;
  top: -7px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: radial-gradient(circle, #FFFFFF 0%, #FFF3C4 42%, rgba(240, 212, 124, 0) 78%);
  box-shadow:
    0 0 18px 6px rgba(255, 243, 196, 0.95),
    0 0 48px 18px rgba(240, 212, 124, 0.55);
}

/* 长尾：自头部向右上方拖出的渐消光带 */
.summon-comet::before {
  content: "";
  position: absolute;
  left: 4px;
  top: -2.5px;
  width: 44vw;
  height: 5px;
  border-radius: 999px;
  background: linear-gradient(to left,
    rgba(255, 246, 216, 0.95) 0%,
    rgba(240, 212, 124, 0.55) 30%,
    rgba(240, 212, 124, 0) 100%);
  transform-origin: left center;
  transform: rotate(-32deg);
  filter: blur(1.2px);
}

/* 回声小彗星：更小更淡、错拍出发 */
.comet-echo {
  left: 84%;
  top: 12%;
}

.fx-summon.is-active .comet-echo {
  animation: comet-fly-echo 1.1s cubic-bezier(0.45, 0.05, 0.7, 0.35) 0.3s forwards;
}

.comet-echo .comet-head {
  width: 9px;
  height: 9px;
  left: -4.5px;
  top: -4.5px;
  box-shadow:
    0 0 12px 4px rgba(255, 243, 196, 0.85),
    0 0 30px 10px rgba(240, 212, 124, 0.4);
}

.comet-echo::before {
  width: 26vw;
  height: 3px;
}

/* 撞击点爆闪：彗星落定处金色光环炸开（约在主彗星终点） */
.summon-burst {
  position: absolute;
  left: 38%;
  top: 46%;
  width: min(46vw, 420px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle,
    rgba(255, 253, 240, 0.98) 0%,
    rgba(250, 237, 196, 0.75) 34%,
    rgba(240, 212, 124, 0.3) 58%,
    transparent 76%);
  opacity: 0;
  transform: translate(-50%, -50%) scale(0.15);
}

.fx-summon.is-active .summon-burst {
  animation: summon-burst-pop 0.6s var(--ease-apple) 1.02s forwards;
}

/* ==========================================================================
   [Rev.7] 5星电影化：上下黑边 letterbox + 暗角 vignette
   ========================================================================== */
.fx-letterbox i {
  position: fixed;
  left: 0;
  right: 0;
  height: 9vh;
  background: #14100A;
  z-index: var(--z-letterbox);
  pointer-events: none;
  transition: transform 0.55s var(--ease-apple);
}

.fx-letterbox .lb-top {
  top: 0;
  transform: translateY(-100%);
}

.fx-letterbox .lb-bottom {
  bottom: 0;
  transform: translateY(100%);
}

.fx-letterbox.is-active .lb-top,
.fx-letterbox.is-active .lb-bottom {
  transform: translateY(0);
}

.fx-vignette {
  position: fixed;
  inset: 0;
  z-index: var(--z-vignette);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.55s var(--ease-apple);
  background: radial-gradient(ellipse at 50% 46%,
    transparent 42%,
    rgba(30, 22, 8, 0.38) 74%,
    rgba(20, 15, 5, 0.62) 100%);
}

.fx-vignette.is-active {
  opacity: 1;
}

/* ==========================================================================
   [Rev.7] 屏幕震动：body.is-shaking 时整个舞台微震（stage.js 定时摘除）
   ========================================================================== */
body.is-shaking .app {
  animation: screen-shake 0.45s linear;
}
