/* ==========================================================================
   知味 V1 · 动效层（vi-motion.css）
   --------------------------------------------------------------------------
   这一层只回答一个问题：**宋的美学，怎么在屏幕上动起来。**

   宋不是"静"。宋画讲气韵生动，书法讲行气，汝窑讲开片——
   那些都是"动"，只是动得极慢、极轻、几乎察觉不到。
   所以这一层禁止三件事：
     · 不做弹跳（那是 iOS 的语汇，不是宋的）
     · 不做旋转（宋的东西不转，它生长）
     · 不做位移超过 12px（那不是"显"，是"飞进来"）

   六条：
     1 显影 Develop   进入不是淡入，是墨落在纸上慢慢显形
     2 墨渗 Bleed     悬停时色从指针处向外洇开
     3 提按 Press     按下有下沉与墨点，像毛笔落纸
     4 呼吸 Breathe   印章与符号以 6.4s 极慢呼吸
     5 行气 Flow      滚动时文字行有纵向微差（滚动驱动）
     6 收笔 Exit      离场反向显影，比进入快（进慢出快）

   🔴 一条安全线：所有隐藏元素的初始态由 `html.vi-js` 前缀控制。
      脚本没加载、报错、或用户禁用 JS → `vi-js` 类不存在 → 内容照常显示。
      "动效失败导致内容看不见"是这类改造最容易犯的致死错误。
   ========================================================================== */

:root {
  /* 动效令牌（本层唯一出处）。命名对齐体系里那五色，不另起一套。 */
  --vi-dur-develop: 640ms;   /* 显影：慢，要能看清"墨在渗" */
  --vi-dur-exit: 240ms;      /* 收笔：快，离开不该拖泥带水 */
  --vi-dur-press: 140ms;
  --vi-dur-hover: 240ms;
  --vi-dur-breathe: 6.4s;
  --vi-ease-develop: cubic-bezier(.16, 1, .3, 1);   /* 快起慢收，像墨渗开后停住 */
  --vi-ease-exit: cubic-bezier(.4, 0, 1, 1);
  --vi-blur-develop: 6px;
  --vi-lift-develop: 10px;
}

/* --------------------------------------------------------------------------
   1 · 显影
   -------------------------------------------------------------------------- */
@keyframes vi-develop {
  from { opacity: 0; filter: blur(var(--vi-blur-develop)); transform: translateY(var(--vi-lift-develop)) scale(.988); }
  to   { opacity: 1; filter: blur(0); transform: none; }
}
@keyframes vi-exit {
  from { opacity: 1; filter: blur(0); transform: none; }
  to   { opacity: 0; filter: blur(4px); transform: scale(1.006); }
}

html.vi-js [data-vi-reveal]:not(.is-in) { opacity: 0; }
[data-vi-reveal].is-in { animation: vi-develop var(--vi-dur-develop) var(--vi-ease-develop) both; }

/* 依次显现：同组元素错开 80ms，形成"一行一行写下来"的节奏。
   为什么不给每个都设 delay：delay 一多，最后那个要等一秒，
   读的人会以为"页面卡了"。错开 80ms 是"看得出先后、又不用等"。 */
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(1) { animation-delay: 0ms; }
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(2) { animation-delay: 80ms; }
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(3) { animation-delay: 160ms; }
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(4) { animation-delay: 240ms; }
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(5) { animation-delay: 320ms; }
[data-vi-stagger] > [data-vi-reveal].is-in:nth-child(n+6) { animation-delay: 380ms; }

/* --------------------------------------------------------------------------
   2 · 墨渗
   -------------------------------------------------------------------------- */
.vi-bleed { position: relative; overflow: hidden; isolation: isolate; }
.vi-bleed::before {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(circle 140px at var(--vi-mx, 50%) var(--vi-my, 50%),
              rgba(168, 57, 46, .085), transparent 68%);
  opacity: 0;
  transition: opacity var(--vi-dur-hover) var(--ease-out);
  pointer-events: none;
  z-index: 0;
}
.vi-bleed:hover::before { opacity: 1; }
/* 子元素要在渗透层之上，否则墨盖住字 */
.vi-bleed > * { position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   3 · 提按
   -------------------------------------------------------------------------- */
.vi-press {
  transition: transform var(--vi-dur-press) var(--ease),
              box-shadow var(--vi-dur-press) var(--ease);
}
.vi-press:active {
  transform: translateY(1px) scale(.995);
}

/* 按钮上的墨点：按下时从中心扩散一小圈，像毛笔落纸的那一下 */
@keyframes vi-ink {
  from { opacity: .5; transform: scale(.2); }
  to   { opacity: 0; transform: scale(1); }
}

/* --------------------------------------------------------------------------
   4 · 呼吸（只给符号与印章，不给正文）
   -------------------------------------------------------------------------- */
/* 呼吸改成非对称：吸 4 秒、呼 6 秒（V2 P5）
 *
 * 原来是 6.4s 匀速正弦——那不是呼吸，是"灯在闪"。
 * 真人吸短呼长，关键帧位置一偏，观感立刻从"机器"变成"活的"。
 * 10s 一轮，40% 处吸满，剩下 6s 呼出去。 */
@keyframes vi-breathe {
  0%   { opacity: .86; }   /* 呼尽 */
  40%  { opacity: 1; }     /* 吸满 */
  100% { opacity: .86; }   /* 呼尽 */
}
.vi-breathe { animation: vi-breathe 10s ease-in-out infinite; }

/* --------------------------------------------------------------------------
   5 · 行气（滚动驱动）
   --------------------------------------------------------------------------
   用 CSS scroll-driven animation，不占主线程、不写一行 JS。
   不支持的浏览器（Safari < 26）用 @supports 挡住，正文照常静态显示——
   这条动效是"锦上添花"，不是内容的一部分。
   -------------------------------------------------------------------------- */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .vi-flow > p {
      animation: vi-flow linear both;
      animation-timeline: view();
      animation-range: entry 6% cover 26%;
    }
    @keyframes vi-flow {
      from { transform: translateY(7px); opacity: .72; }
      to   { transform: none; opacity: 1; }
    }

    /* 关于"顶部墨线进度条"：写好了，又删了。
       它必须贴在 sticky 导航的下缘，而导航高度是响应式的，
       要么把高度写死（换屏就错位），要么用 JS 同步（多一处可能失效的耦合）。
       为一条装饰线付这个代价不值 —— 而且那条线一直在动，读长文时是干扰。
       行气靠"正文行的纵向微差"就够了，那是内容自己的呼吸。 */
  }
}

/* --------------------------------------------------------------------------
   6 · 收笔（页面间过渡）
   --------------------------------------------------------------------------
   View Transitions API：同源跳转时整页做一次"显影/收笔"。
   不支持时浏览器按普通跳转处理，**不需要任何降级代码**——
   这是它比"自己写遮罩层"好的地方：失败是静默的、且必然是好的那种失败。
   -------------------------------------------------------------------------- */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: vi-exit var(--vi-dur-exit) var(--vi-ease-exit) both;
}

/* 墨滴入水（V2 P6）
 *
 * 新页面不是"淡入"，是从**你手指落下的那一点**向外洇开。
 * 这是整套动效里唯一一件"让人记住"的事——
 * 因为每次跳转都从他自己点的位置开始，而不是从屏幕中心。
 *
 * 为什么不用整页 blur 显影：那两条一起上会糊成一团。
 * 页面转场用墨滴，"块显影"留给滚动——各管一段，不抢。
 */
::view-transition-new(root) {
  clip-path: circle(0 at var(--vt-x, 50%) var(--vt-y, 50%));
  animation: vi-ink 680ms cubic-bezier(.2, .8, .3, 1) both;
}
@keyframes vi-ink {
  from { clip-path: circle(0 at var(--vt-x, 50%) var(--vt-y, 50%)); }
  to   { clip-path: circle(150vmax at var(--vt-x, 50%) var(--vt-y, 50%)); }
}

/* --------------------------------------------------------------------------
   7 · 纸
   --------------------------------------------------------------------------
   极淡的纤维噪点。它的作用不是"好看"，是让大片纸色不发"塑料光"。
   纯色底在 OLED 屏上会有色带，加一层 2.5% 的噪点就消失了。
   用 SVG feTurbulence 内联，不引外部图片、不额外发请求。
   -------------------------------------------------------------------------- */
.vi-paper::after {
  content: "";
  position: fixed; inset: 0;
  pointer-events: none;
  z-index: 1;
  opacity: .028;
  background-image: url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='140' height='140'>\
<filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/></filter>\
<rect width='140' height='140' filter='url(%23n)'/></svg>");
  background-size: 140px 140px;
  mix-blend-mode: multiply;
}

/* --------------------------------------------------------------------------
   8 · 降级：系统设了"减少动效"就全关
   --------------------------------------------------------------------------
   这不是可选项。前庭功能障碍的人看视差与位移会眩晕，
   而"品牌要动起来"永远不该赢过"有人会不舒服"。
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html.vi-js [data-vi-reveal]:not(.is-in) { opacity: 1; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .vi-paper::after { display: none; }
}
