/* ══════════════════════════════════════════════════════════════════════
   晨雾 · 动效层（全站共用，opt-in：页面里没有这些 class 就完全不生效）
   ──
   signature easing  cubic-bezier(.16,1,.3,1)  expo-out
   duration palette  quick .24s / standard .52s / slow 1.1s · stagger 70ms
   铁律：
   1) rAF 循环里只读 scrollY，几何量一律缓存 —— 每帧 getBoundingClientRect 会强制重排，就是卡顿的来源
   2) 自定义光标只在 (pointer:fine) 下接管；实心点写在 mousemove 里保证零延迟，环只做拖尾装饰
   3) prefers-reduced-motion 与 html.no-motion 都必须能整体降级
   ══════════════════════════════════════════════════════════════════════ */

:root{
  --e:cubic-bezier(.16,1,.3,1);
  --e2:cubic-bezier(.2,0,0,1);
  --d1:.24s; --d2:.52s; --d3:1.1s; --stg:70ms;
}

/* ── 连续色场：三团柔光在纸面上漂移，段落到哪哪团抬起来 ── */
.field{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.field > span{position:absolute;display:block;border-radius:50%;filter:blur(48px);
  will-change:transform,opacity;opacity:.85;
  transition:transform var(--d3) var(--e),opacity var(--d3) var(--e)}
.field .f-sl{width:64vw;height:64vw;left:-14vw;top:-18vw;
  background:radial-gradient(circle,var(--shenglin-wash),transparent 66%);
  animation:m-drift1 26s var(--e2) infinite}
.field .f-gl{width:58vw;height:58vw;right:-16vw;top:6vh;
  background:radial-gradient(circle,var(--glacier-wash),transparent 66%);
  animation:m-drift2 32s var(--e2) infinite}
.field .f-lm{width:70vw;height:70vw;left:16vw;bottom:-26vw;
  background:radial-gradient(circle,var(--lumen-wash),transparent 66%);
  animation:m-drift3 29s var(--e2) infinite}
@keyframes m-drift1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(7vw,6vh) scale(1.09)}}
@keyframes m-drift2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-6vw,9vh) scale(1.12)}}
@keyframes m-drift3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(5vw,-7vh) scale(1.07)}}
.field.on-sl .f-sl{opacity:1} .field.on-sl .f-gl,.field.on-sl .f-lm{opacity:.38}
.field.on-gl .f-gl{opacity:1} .field.on-gl .f-sl,.field.on-gl .f-lm{opacity:.38}
.field.on-lm .f-lm{opacity:1} .field.on-lm .f-sl,.field.on-lm .f-gl{opacity:.38}

/* 细网格：只在画面中部显影，边缘羽化掉 */
.mesh{position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.55;
  background-image:linear-gradient(var(--rule) 1px,transparent 1px),
                   linear-gradient(90deg,var(--rule) 1px,transparent 1px);
  background-size:96px 96px;
  -webkit-mask-image:radial-gradient(70% 60% at 50% 30%,#000,transparent 78%);
  mask-image:radial-gradient(70% 60% at 50% 30%,#000,transparent 78%)}

/* ── 光标：点=零延迟跟手，环=拖尾装饰 ── */
.mcur,.mdot{display:none}
.mcur{position:fixed;left:0;top:0;z-index:900;width:0;height:0;pointer-events:none;
  will-change:transform;opacity:0;transition:opacity .35s var(--e)}
.mcur .ring{position:absolute;left:-16px;top:-16px;width:32px;height:32px;border-radius:50%;
  border:1.5px solid var(--ink);
  transition:transform var(--d1) var(--e),border-color var(--d1),background var(--d1)}
.mdot{position:fixed;left:0;top:0;z-index:901;width:6px;height:6px;margin:-3px 0 0 -3px;
  border-radius:50%;background:var(--ink);pointer-events:none;will-change:transform;
  opacity:0;transition:opacity .35s var(--e)}
.mcur.on,.mdot.on{opacity:1}
.mcur.big .ring{transform:scale(1.85);background:rgba(255,255,255,.5)}
.mcur.sl .ring{border-color:var(--shenglin)} .mcur.gl .ring{border-color:var(--glacier)}
.mcur.lm .ring{border-color:var(--lumen)}
.mcur.big.sl .ring{background:var(--shenglin-wash)}
.mcur.big.gl .ring{background:var(--glacier-wash)}
.mcur.big.lm .ring{background:var(--lumen-wash)}
.mdot.sl{background:var(--shenglin)} .mdot.gl{background:var(--glacier)} .mdot.lm{background:var(--lumen)}
@media (pointer:fine){
  html.mcur-on body,html.mcur-on a,html.mcur-on button,html.mcur-on [role="button"]{cursor:none}
  html.mcur-on .mcur,html.mcur-on .mdot{display:block}
}

/* ── 滚动进度 ── */
.mprog{position:fixed;top:0;left:0;height:2px;width:0;z-index:920;
  background:linear-gradient(90deg,var(--shenglin),var(--glacier) 52%,var(--lumen))}

/* ── 揭示原语 ── */
.rv{opacity:0;transform:translateY(26px);
  transition:opacity var(--d3) var(--e),transform var(--d3) var(--e)}
.rv.in{opacity:1;transform:none}
.mask{display:block;overflow:hidden}
.mask > b{display:block;font-weight:inherit;transform:translateY(105%);
  transition:transform 1.15s var(--e)}
.in .mask > b,.mask.in > b{transform:none}
.wipe{clip-path:inset(0 100% 0 0);transition:clip-path 1.15s var(--e) var(--dl,0s)}
.wipe.in{clip-path:inset(0 0 0 0)}

/* ── 里程表数字：每位一列 0-9，逐位滚到目标 ── */
.dig{display:inline-block;height:1em;overflow:hidden;width:.58em;vertical-align:top}
.dig i{display:block;font-style:normal;transform:translateY(0);
  transition:transform 1.15s var(--e) var(--dl,0s)}
.dig i s{display:block;height:1em;line-height:1;text-align:center;text-decoration:none}
.dig.sep{width:.3em}
.dig.in i{transform:translateY(calc(var(--n) * -1em))}

/* ── 整体降级 ── */
@media (prefers-reduced-motion:reduce){
  .field > span{animation:none}
  .rv,.mask > b{opacity:1;transform:none;transition:none}
  .wipe{clip-path:none;transition:none}
  .dig i{transition:none}
}
html.no-motion .field > span{animation:none}
html.no-motion .rv,html.no-motion .mask > b{opacity:1;transform:none;transition:none}
html.no-motion .wipe{clip-path:none;transition:none}
html.no-motion .dig i{transition:none}
html.no-motion .mcur,html.no-motion .mdot{display:none}
