  .beam {
    position: absolute; top: 0;
    width: 204px; margin-left: -102px;
    transform: scaleX(var(--bw-scale, 1));
    transform-origin: 50% 50%;
    opacity: 0;
    pointer-events: none;
    z-index: 2;
    --hit: 0;                 /* 判定段进度 0→1：蓝色层与蓝色边框一起淡入 */
    --rise: 200px;            /* 光柱高度：星星从底部升到顶部 */
    --tile: 140px;            /* 网点贴图高度：决定循环位移（204px 宽 × 0.685） */
    filter: drop-shadow(0 0 12px rgba(255, 196, 80, .55));
    transition: opacity .18s ease-out;
  }
  .beam.on { opacity: 1; }

  .beam-bg {
    position: absolute;
    left: 50%; top: 50%;
    width: 106.93%; height: 107.66%;
    transform: translate(-50%, -50%);
    background: url("./assets/game/beam/beam-bg.webp") center / 100% 100% no-repeat;
    pointer-events: none;
  }

  .beam-base {
    position: absolute;
    left: 50%; top: 100%;
    width: 260px; height: 260px;
    margin: -130px 0 0 -130px;
    border-radius: 50%;
    transform: scaleY(calc(.42 * var(--bw-scale, 1)));
    background:
      radial-gradient(closest-side,
        rgba(205, 242, 255, var(--hit)) 0%,
        rgba(168, 224, 255, calc(var(--hit) * .92)) 58%,
        rgba(168, 224, 255, 0) 82%),
      radial-gradient(closest-side,
        rgba(255, 248, 176, 1) 0%,
        rgba(255, 238, 120, .98) 55%,
        rgba(255, 228, 88, 0) 84%);
    filter: blur(.6px);
    pointer-events: none;
  }

  .beam-body {
    position: absolute; inset: 0;
    overflow: hidden;
    background: url("./assets/game/beam/beam-range.webp") center / 100% 100% no-repeat;
    -webkit-mask: url("./assets/game/beam/beam-range.webp") center / 100% 100% no-repeat;
    mask: url("./assets/game/beam/beam-range.webp") center / 100% 100% no-repeat;
  }
  /* 流动网点 / 斜纹：用 transform 位移代替 background-position，
   * 位移动画可走合成层，不再每帧重绘两层贴图；
   * 元素向下多留一个贴图高度，保证位移过程中始终铺满（视觉与原来逐像素一致） */
  .beam-dots {
    position: absolute; inset: -2px 0 calc(-1 * var(--tile));
    background: url("./assets/game/beam/beam-dots.webp") center top / 100% auto repeat-y;
    opacity: .6;
    animation: beamFlow 1.32s linear infinite;
  }
  @keyframes beamFlow {
    from { transform: translateY(0); }
    to   { transform: translateY(calc(-1 * var(--tile))); }
  }
  .beam-blue, .beam-frame-blue {
    transform: scale(.92);
  }
  .beam-blue {
    position: absolute; inset: 0;
    overflow: hidden;
    background: url("./assets/game/beam/beam-blue-range.webp?v=2") center / 100% 100% no-repeat;
    -webkit-mask: url("./assets/game/beam/beam-blue-range.webp?v=2") center / 100% 100% no-repeat;
    mask: url("./assets/game/beam/beam-blue-range.webp?v=2") center / 100% 100% no-repeat;
  }
  .beam-hatch {
    position: absolute; inset: 0 0 calc(-1 * var(--tile));
    background: url("./assets/game/beam/beam-hatch.webp") center top / 100% auto no-repeat;
    animation: beamFlow .31s linear infinite;
    --tile: 32.64px;
  }
  .beam-star {
    position: absolute; top: 100%;
    width: var(--w, 20px);
    transform: translate(-50%, 0);
    opacity: 0;
    animation: beamStarRise var(--star-dur, 2s) linear infinite;
    animation-delay: var(--delay, 0s);
    filter: drop-shadow(0 0 4px rgba(255, 240, 170, .8));
  }
  .beam-star img { display: block; width: 100%; height: auto; }
  @keyframes beamStarRise {
    0%   { opacity: 0; transform: translate(-50%, 0) scale(.85); }
    12%  { opacity: .95; }
    70%  { opacity: .8; }
    100% { opacity: 0; transform: translate(-50%, calc(-1 * var(--rise))) scale(1.05); }
  }
  .beam-frame {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: fill;
    pointer-events: none;
  }
  .beam-frame-blue {
    opacity: .95;
    transition: opacity .2s ease, filter .2s ease;
  }
  .beam.peak .beam-frame-blue { opacity: 1; filter: brightness(1.3); }

  .beam.peak {
    filter: drop-shadow(0 0 24px rgba(140, 215, 255, .95)) brightness(1.12);
  }

  .beam-spark {
    position: absolute;
    width: 5px; height: 5px; border-radius: 50%;
    background: #fff6cf;
    box-shadow: 0 0 8px rgba(255,214,110,.95);
    pointer-events: none;
    z-index: 2;
    animation: sparkUp .9s ease-out forwards;
  }
  @keyframes sparkUp {
    0%   { transform: translateY(0) scale(.6); opacity: 0; }
    30%  { opacity: 1; }
    100% { transform: translateY(-130px) scale(1); opacity: 0; }
  }

