/* ============================================================
   motion.css · 入场编排
   仅在 <html class="js"> 时隐藏内容；脚本关闭时一切可见
   ============================================================ */

/* ---------- 块级入场：模糊上浮，逐个揭示 ---------- */
.js .reveal{
  opacity:0;
  transform:translateY(20px);
  filter:blur(7px);
  transition:
    opacity 1.1s var(--ease),
    transform 1.1s var(--ease),
    filter 1.1s var(--ease);
  transition-delay:var(--rd,0ms);
  will-change:opacity,transform;
}
.js .reveal.in{
  opacity:1;transform:none;filter:none;
}
.js .reveal.d1{--rd:120ms}
.js .reveal.d2{--rd:260ms}
.js .reveal.d3{--rd:400ms}
.js .reveal.d4{--rd:540ms}

/* 材料卡：从斜下方稍稍抬起，比正文更有分量 */
.js .reveal.lift{
  transform:translateY(30px) scale(.985);
}
.js .reveal.lift.in{transform:none}

/* ---------- 首屏：先让世界出现，再让字落下 ---------- */
.js .panel.hero .reveal.d1{--rd:.45s}
.js .panel.hero .reveal.d2{--rd:.75s}
.js .panel.hero .reveal.d3{--rd:1.05s}

/* ---------- 展示字：逐字显影（arriveShim） ---------- */
.display{
  --sweep:1.0s;
  --jit:.16s;
  --dur:1.05s;
  --blur:4px;
}
.display .wd{display:inline-block;white-space:nowrap}
.display .c{position:relative;display:inline-block}
.js .display.split .c{opacity:0}
.js .display.play .c{
  opacity:0;
  animation:arriveShim var(--dur) cubic-bezier(.4,0,.2,1)
    calc(var(--sweep) * var(--fi,0) + var(--jit) * var(--j1,0)) forwards;
}
.display.play .c.settled{animation:none;opacity:1;filter:none;transform:none}

@keyframes arriveShim{
  0%{opacity:0;filter:blur(var(--blur));transform:translateY(6px)}
  28%{opacity:.55;filter:blur(calc(var(--blur) * .55))}
  52%{opacity:.82;filter:blur(calc(var(--blur) * .28));transform:translateY(2px)}
  74%{opacity:.95;filter:blur(calc(var(--blur) * .1))}
  100%{opacity:1;filter:none;transform:none}
}

/* 一两笔金色的"返光"，让标题像被漏下的光扫到 */
.display .c.flick::after{
  content:attr(data-ch);
  position:absolute;left:0;top:0;
  pointer-events:none;opacity:0;
  color:color-mix(in srgb,var(--c-gold) 58%,#eef0e2);
  text-shadow:0 0 16px rgba(217,168,90,.5),0 3px 44px rgba(0,0,0,.55);
}
.display.play .c.flick::after{
  animation:fleckFade 6.5s ease-in-out calc(2.6s + var(--gj,0) * 6.5s) infinite;
}
.display.idle .c.flick::after{animation-play-state:paused}
@keyframes fleckFade{
  0%,100%{opacity:0}
  4%{opacity:0}
  9%{opacity:1}
  17%{opacity:0}
}

/* ---------- 大句：以词为单位，轻轻落位 ---------- */
.js .breathline .ch{opacity:0;display:inline-block}
.js .breathline .wd{display:inline-block;white-space:nowrap}
.js .breathline.in .ch{
  animation:hopIn .8s cubic-bezier(.34,1.3,.5,1) forwards;
  animation-delay:calc(var(--i,0) * 55ms + var(--wi,0) * 70ms);
}
.js .breathline.settled .ch{
  animation:none;opacity:1;filter:none;transform:none;
}
@keyframes hopIn{
  0%{opacity:0;transform:translateY(.1em);filter:blur(2px)}
  62%{opacity:1;transform:translateY(-.07em);filter:blur(.4px);
      text-shadow:0 0 12px rgba(217,168,90,.42),0 2px 30px rgba(0,0,0,.6)}
  86%{transform:translateY(.012em);filter:none}
  100%{opacity:1;transform:none;text-shadow:0 2px 34px rgba(0,0,0,.66),0 1px 6px rgba(0,0,0,.4)}
}

/* ---------- 相框入场：从画面外推近 ---------- */
.js .plate.reveal{transform:translateY(26px) scale(.985)}
.js .plate.reveal.in{transform:none}

/* ---------- 行程图：走过的段落点亮 ---------- */
.rail i.on{animation:railPulse 2.6s ease-in-out infinite}
@keyframes railPulse{
  0%,100%{box-shadow:0 0 10px rgba(217,168,90,.55)}
  50%{box-shadow:0 0 18px rgba(217,168,90,.9)}
}

/* ---------- 降级：减少动效 ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.001ms !important;
    scroll-behavior:auto !important;
  }
  .js .reveal{opacity:1;transform:none;filter:none}
  .js .display.split .c{opacity:1;animation:none}
  .js .breathline .ch{opacity:1;animation:none}
  .display .c.flick::after{display:none}
  .dap-a,.dap-b{animation:none}
  .sheen i{animation:none;opacity:.2}
}
