/* ==========================================================================
   LUMEN · holo — 全息闪光卡（foil / holo card）
   图库卡片的「闪光卡」效果：轻微的 3D 倾斜 + 一层随指针流动的彩虹反光。

   这一层只做样式，不改 .card 的 DOM 结构：holo.js 往 .card__media 内部
   append 两个绝对定位层（.card__media 本来就 overflow:hidden，再被 .card
   的圆角裁切，正好当取景框）：

       .card.is-holo > .card__media > .holo__shine   彩虹箔
                                    > .holo__glare   跟着指针的镜面高光

   所有逐帧数值由 JS 写在 .card 的 CSS 自定义属性上，不直接写 transform：

     --holo-rx / --holo-ry   倾斜角（deg）   rotateX / rotateY
     --holo-x  / --holo-y    指针位置（%）   彩虹高光圆心
     --holo-bx / --holo-by   箔片背景位置（%）双 spring 的慢轴
     --holo-i                交互强度 0..1   进入 1，离开 0
     --holo-d                指针离中心距离 0..1（控制反光亮度）

   外观参数（LUMEN.holo.setOptions 写到 .card 的内联样式，这里给兜底值）：
     --holo-intensity  0..1    彩虹层不透明度（默认 0.5）
     --holo-tilt       0..20   最大倾斜角度（默认 10）
     --holo-shine      0..1    高光强度（默认 0.6）
     --holo-speed      0.4..2  弹簧响应速度（默认 1，由 JS 使用）

   对应脚本：demo/js/holo.js（window.LUMEN.holo）
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 状态变量 + 参数兜底
   -------------------------------------------------------------------------- */
.card.is-holo {
  /* 逐帧状态（holo.js 写在元素内联样式上，这里只是首帧兜底） */
  --holo-rx: 0deg;
  --holo-ry: 0deg;
  --holo-x: 50%;
  --holo-y: 50%;
  --holo-bx: 50%;
  --holo-by: 50%;
  --holo-i: 0;
  --holo-d: 0;

  /* 外观参数 */
  --holo-intensity: 0.5;
  --holo-tilt: 10;
  --holo-shine: 0.6;
  --holo-speed: 1;

  /* 彩虹箔的几何常量 */
  --holo-angle: 133deg;
  --holo-space: 6%;
}

/* --------------------------------------------------------------------------
   2. 会倾斜的平面 = .card__media
      倾斜只加在 media 上（.card 自己的 hover 样式保持不动），角度来自上面的
      变量，所以 JS 不需要写 el.style.transform。
   -------------------------------------------------------------------------- */
.card.is-holo .card__media {
  transform-origin: 50% 50%;
  /* 没有指针时完全不 transform：一屏十几张卡不该各自占一个合成层 */
  transition: none;
}
.card.is-holo.is-holo-live .card__media {
  transform: perspective(800px) rotateX(var(--holo-rx)) rotateY(var(--holo-ry));
  will-change: transform;
}
/* 指针离开、弹簧交棒给 CSS 的那一下用它补完，避免硬切 */
.card.is-holo.is-holo-settling .card__media {
  transition: transform 320ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* 倾斜层和图片的 hover 缩放不能同时存在：两个 transform 会互相打架 */
.card.is-holo .card__media img,
.card.is-holo .card__media video,
.card.is-holo:hover .card__media img,
.card.is-holo:hover .card__media video,
.card.is-holo:active .card__media img,
.card.is-holo:active .card__media video {
  transform: none;
}

/* 现有 .card__glare 也是跟着鼠标的径向高光，和 .holo__glare 重复；
   is-holo 时只保留全息层自己的高光（纯 CSS 控制，不动 gallery.js） */
.card.is-holo .card__glare {
  display: none;
}

/* --------------------------------------------------------------------------
   3. 全息层
   -------------------------------------------------------------------------- */
.card.is-holo .holo__shine,
.card.is-holo .holo__glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  /* 层在图片之上、卡片的勾选/播放图标之下（见下面第 5 节） */
  z-index: 1;
}

/* 彩虹箔：两层渐变（彩虹条 + 斜向层压光栅），配方改自 闪卡效果/css.txt。
   参考实现用 color-dodge 叠一张外部 foil 贴图、色带 1100% 只露一条，且没有
   遮罩 —— 整卡都被染色。本项目不能联网拿贴图，壁纸又普遍偏亮，直接照搬会
   把画面洗白、变成一张彩色滤镜；所以做两处改动：
     1) 用 overlay 混合（保明暗、只上色），色带收到一屏约 2.5 圈，能读出彩虹；
     2) 用 mask 把这一层裁成「指针附近的一块」，卡面其余部分完全不染色 ——
        反光才是「跟着指针走的一片」，而不是整张图换了颜色。
   测试页 holo-test.html 的 ?pos=left / ?pos=right 就是固定 --holo-x/--holo-y
   拍两张对比图，验证这块反光真的在移动。 */
.card.is-holo .holo__shine {
  background-image:
    /* 彩虹条：色带随 --holo-bx/--holo-by 滑动（双 spring 的慢轴） */
    repeating-linear-gradient(
      -33deg,
      hsl(2 92% 58%) 0%,
      hsl(228 88% 66%) calc(var(--holo-space) * 1),
      hsl(176 86% 48%) calc(var(--holo-space) * 2),
      hsl(123 88% 44%) calc(var(--holo-space) * 3),
      hsl(283 94% 62%) calc(var(--holo-space) * 4),
      hsl(2 92% 58%) calc(var(--holo-space) * 5)
    ),
    /* 斜向的层压硬光栅：给彩虹加上「金属拉丝」的明暗节奏 */
    repeating-linear-gradient(
      var(--holo-angle),
      rgba(6, 12, 30, 0.5) 0%,
      rgba(170, 245, 255, 0.45) 2%,
      rgba(240, 255, 252, 0.42) 4%,
      rgba(170, 245, 255, 0.45) 6%,
      rgba(6, 12, 30, 0.5) 8%,
      rgba(6, 12, 30, 0.5) 12%
    );
  background-size: 300% 300%, 460% 460%;
  background-position: var(--holo-bx) var(--holo-by),
    var(--holo-bx) var(--holo-by);
  background-blend-mode: normal, soft-light;
  mix-blend-mode: overlay;
  /* 只做轻量颜色处理，不用 filter: blur() 这类重效果 */
  filter: saturate(1.45);
  opacity: calc(var(--holo-i) * var(--holo-intensity) * 1.7);

  /* 把彩虹裁在指针周围：椭圆用百分比，随卡片尺寸缩放；
     向外 alpha 衰减到 0，所以边缘不会出现硬边 */
  -webkit-mask-image: radial-gradient(
    ellipse 70% 70% at var(--holo-x) var(--holo-y),
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 0.72) 42%,
    rgba(0, 0, 0, 0) 100%
  );
  mask-image: radial-gradient(
    ellipse 70% 70% at var(--holo-x) var(--holo-y),
    rgba(0, 0, 0, 1) 0%,
    rgba(0, 0, 0, 0.72) 42%,
    rgba(0, 0, 0, 0) 100%
  );
}

/* 镜面高光：圆心锁在指针上，用 soft-light 而不是 hard-light —— 后者在亮图上
   会直接把一块像素顶到纯白。离开时跟着 --holo-i 一起淡出。 */
.card.is-holo .holo__glare {
  z-index: 2;
  background-image: radial-gradient(
    140px circle at var(--holo-x) var(--holo-y),
    hsla(0 0% 100% / 0.45) 0%,
    hsla(0 0% 100% / 0) 100%
  );
  mix-blend-mode: soft-light;
  opacity: calc(
    var(--holo-shine) * var(--holo-i) * (0.3 + var(--holo-d) * 0.5)
  );
}

/* 指针离开、由 rAF 交棒给 CSS 的最后一小段：高光和背景位置也补完 */
.card.is-holo.is-holo-settling .holo__shine,
.card.is-holo.is-holo-settling .holo__glare {
  transition: opacity 320ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
    background-position 320ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1));
}

/* --------------------------------------------------------------------------
   4. 减少动效：静态高光，不做倾斜
      JS 侧同样会走静态分支（html[data-motion="off"] / prefers-reduced-motion
      任一成立都不绑指针监听）；CSS 这里再兜一层，保证任何情况下都不歪。
   -------------------------------------------------------------------------- */
.card.is-holo.is-holo-static .card__media,
.card.is-holo.is-holo-static.is-holo-live .card__media {
  transform: none;
  transition: none;
  will-change: auto;
}

@media (prefers-reduced-motion: reduce) {
  .card.is-holo .card__media,
  .card.is-holo.is-holo-live .card__media {
    transform: none;
    transition: none;
    will-change: auto;
  }
  .card.is-holo.is-holo-settling .card__media,
  .card.is-holo.is-holo-settling .holo__shine,
  .card.is-holo.is-holo-settling .holo__glare {
    transition: none;
  }
}

html[data-motion="off"] .card.is-holo .card__media,
html[data-motion="off"] .card.is-holo.is-holo-live .card__media {
  transform: none;
  transition: none;
  will-change: auto;
}
html[data-motion="off"] .card.is-holo.is-holo-settling .card__media,
html[data-motion="off"] .card.is-holo.is-holo-settling .holo__shine,
html[data-motion="off"] .card.is-holo.is-holo-settling .holo__glare {
  transition: none;
}

/* --------------------------------------------------------------------------
   5. 卡片自带的勾选 / 播放图标要压在彩虹层上面
   -------------------------------------------------------------------------- */
.card.is-holo .card__media .card__check,
.card.is-holo .card__media .card__play {
  z-index: 3;
}
