/* =========================================================
   Qi-theme — 高级动效层（motion）
   ---------------------------------------------------------
   职责：只负责「元素的初始隐藏态」与「悬停微交互」。
   位移 / 缓动 / 时长 / 视差的计算与播放由 assets/js/motion.js 负责。

   ⚠ 契约（三条，改动任一处必须三处同步）：
     1) 本文件所有「初始隐藏态」选择器，必须与 motion.js 的
        TARGETS / HIDDEN_SEL 完全一致；
     2) 所有初始隐藏态都带 :not(.qi-in)。元素动画结束由 JS 挂上 .qi-in 并
        清除内联样式，等于把这个元素「交还」给常规样式表 —— 这样
        卡片悬停位移、图片悬停放大等既有 CSS 交互才不会被打架的内联
        transform 顶掉；
     3) 同时要求 html.qi-motion 且 html 不带 .qi-motion-off。

   由此得到的四种安全边界：
     · JS 被禁用         → 引导脚本不执行 → 没有 .qi-motion → 内容直接可见
     · 用户开启「减弱动态」→ 引导脚本提前 return → 内容直接可见
     · 引擎加载/执行失败  → 4s 看门狗挂 .qi-motion-off → 内容直接可见
     · 引擎正常运行      → 逐元素挂 .qi-in 交接，无内联样式残留

   性能：只操作 transform / opacity / clip-path（合成层属性，不触发重排）。
   ⚠ 不要再给元素加 will-change。此前曾把 will-change:transform 广播给全部
     .rb img / .rb .ph，等于让页面上每一张图各自提升为独立合成层，显存暴涨、
     移动端容易崩；GSAP 在补间期间会自行处理合成提示，无需外力。

   ── 已移除的动画形式（勿回退，判据见 inc/motion.php 顶部）────────────
     · 首屏幕布（mask/curtain 注入色块）：把 LCP 区域盖上再揭开。
     · 标题 compress（scaleX 1.16 / scaleY .74）：非等比缩放文字会重采样发虚。
     · 图片 zoom（放大归位）：与 clip 擦出相比无信息量。
     · 图片视差 + will-change 广播：作用于全部图片，小尺寸元素表现为错位。
   ========================================================= */

/* 由 PHP 按后台设置写入 --mt-dist（此处为兜底默认值，与 inc/motion.php 对齐）。
   只保留 CSS 真正消费的变量：时长与缓动在 JS 侧使用，
   悬停有独立的 --mt-hover-dur —— 死变量会让人误以为改 CSS 就能调节奏。 */
:root {
  --mt-dist: 44px;
  /* 悬停节奏独立于「入场节奏」：入场时长可达 2.4s，拿它驱动 hover 会变得粘滞 */
  --mt-hover-dur: 320ms;
  --mt-hover-ease: cubic-bezier(.22, 1, .36, 1);
}

/* =========================================================
   1) 导航栏入场
   只做位移、不做淡入：-102% 时整个 header 已在视口之外，
   再叠 opacity 只会在动画被中断时留下「半透明导航」的观感。
   ========================================================= */
html.qi-motion.qi-mt-nav:not(.qi-motion-off) .site-header:not(.qi-in) {
  transform: translateY(-102%);
}

/* =========================================================
   2) 区块标题组（英文眉标 → 大标题 → 副标题）
   ========================================================= */
html.qi-motion.qi-mt-head:not(.qi-motion-off) .rb .ey:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .rb h2:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .rb .lead:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .section-head .eyebrow:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .section-head h1:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .section-head h2:not(.qi-in),
html.qi-motion.qi-mt-head:not(.qi-motion-off) .section-head p:not(.qi-in) {
  opacity: 0;
}

/* 形式 A：擦出 —— 文字被自下而上「擦」出来（clip 只裁不缩，不模糊字形） */
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .rb .ey:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .rb h2:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .rb .lead:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .section-head .eyebrow:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .section-head h1:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .section-head h2:not(.qi-in),
html.qi-motion.qi-mt-hd-mask:not(.qi-motion-off) .section-head p:not(.qi-in) {
  clip-path: inset(0 0 100% 0);
}

/* 形式 B：位移 —— 初始位移由 JS 按后台 distance 设定，CSS 只需隐藏 */

/* =========================================================
   3) 卡片依次错峰出现
   容器 = 通用栅格 .grid，以及各区块的行容器（aw-row / tm-row / ts-row /
     cl-row / gl-row / pc-row / pg-row / plan-row / ft-row / ctr-row …）。
   用 [class*="-row"] 而非 [class$="-row"]：行容器常带修饰类
     （如 class="aw-row g3"），属性值并不以 "-row" 结尾，用 $= 会漏匹配。
   不叠 scale：0.986 的缩放在栅格里肉眼不可辨，只是引擎负担；
     且非整数缩放会让卡片内文字产生亚像素抖动。
   ========================================================= */
html.qi-motion.qi-mt-cards:not(.qi-motion-off) .grid > *:not(.qi-in),
html.qi-motion.qi-mt-cards:not(.qi-motion-off) .rb [class*="-row"] > *:not(.qi-in) {
  opacity: 0;
  transform: translateY(calc(var(--mt-dist) * .62));
}

/* =========================================================
   4) 图片揭示（reveal）
   ========================================================= */
html.qi-motion.qi-mt-img:not(.qi-motion-off) .rb img:not(.qi-in),
html.qi-motion.qi-mt-img:not(.qi-motion-off) .rb .ph:not(.qi-in) {
  opacity: 0;
}

/* 形式 A：自下擦出 */
html.qi-motion.qi-mt-im-clip:not(.qi-motion-off) .rb img:not(.qi-in),
html.qi-motion.qi-mt-im-clip:not(.qi-motion-off) .rb .ph:not(.qi-in) {
  clip-path: inset(0 0 100% 0);
}

/* 形式 B：横向擦出（自左向右揭开） */
html.qi-motion.qi-mt-im-curtain:not(.qi-motion-off) .rb img:not(.qi-in),
html.qi-motion.qi-mt-im-curtain:not(.qi-motion-off) .rb .ph:not(.qi-in) {
  clip-path: inset(0 100% 0 0);
}

/* =========================================================
   5) 首屏开幕（opening animation）
   只隐藏首屏自身的元素层；不再注入任何覆盖层。
   ========================================================= */
html.qi-motion.qi-mt-hero:not(.qi-motion-off) .rb-hero .container > *:not(.qi-in),
html.qi-motion.qi-mt-hero:not(.qi-motion-off) .rb-hero-slider .hs-slide.is-active .hs-in > *:not(.qi-in),
html.qi-motion.qi-mt-hero:not(.qi-motion-off) .rb-hero-split .container > *:not(.qi-in) {
  opacity: 0;
}

/* =========================================================
   6) 悬停微交互（纯 CSS，零 JS 负担）
   说明：只在元素被 .qi-in 交接之后才有意义（交接前内联 transform 会覆盖它）
   ========================================================= */
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card {
  transition: transform var(--mt-hover-dur) var(--mt-hover-ease),
              box-shadow var(--mt-hover-dur) var(--mt-hover-ease);
}
/* 上浮 4px：够传达「可点」，8px 在密集栅格里会让卡片明显跳位 */
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 44px rgba(15, 42, 74, .14);
}

/* 图片 / 占位块微放大 —— 作用域收窄到「有交互容器的图」：
   .card 内、<a> 内。给不可点击的正文插图加悬停放大属于假交互暗示。 */
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card img,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card .ph,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb a img,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb a .ph {
  transition: transform var(--mt-hover-dur) var(--mt-hover-ease);
}
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card:hover img,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb .card:hover .ph,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb a:hover img,
html.qi-motion.qi-mt-hover:not(.qi-motion-off) .rb a:hover .ph {
  transform: scale(1.03);
}

/* =========================================================
   7) 无障碍与兜底
   ========================================================= */
/* 引擎未就绪（看门狗触发）→ 强制显示全部内容，绝不留死白块 */
html.qi-motion-off .site-header,
html.qi-motion-off .rb .ey,
html.qi-motion-off .rb h2,
html.qi-motion-off .rb .lead,
html.qi-motion-off .grid > *,
html.qi-motion-off .rb [class*="-row"] > *,
html.qi-motion-off .rb img,
html.qi-motion-off .rb .ph,
html.qi-motion-off .rb-hero .container > *,
html.qi-motion-off .rb-hero-slider .hs-slide.is-active .hs-in > *,
html.qi-motion-off .rb-hero-split .container > *,
html.qi-motion-off .section-head .eyebrow,
html.qi-motion-off .section-head h1,
html.qi-motion-off .section-head h2,
html.qi-motion-off .section-head p {
  opacity: 1 !important;
  transform: none !important;
  clip-path: none !important;
  transition: none !important;
}

/* 用户开启「减弱动态效果」时的二次保险（引导脚本通常直接不挂类，这里再兜一层） */
@media (prefers-reduced-motion: reduce) {
  html.qi-motion .site-header,
  html.qi-motion .rb .ey,
  html.qi-motion .rb h2,
  html.qi-motion .rb .lead,
  html.qi-motion .grid > *,
  html.qi-motion .rb [class*="-row"] > *,
  html.qi-motion .rb img,
  html.qi-motion .rb .ph,
  html.qi-motion .rb-hero .container > *,
  html.qi-motion .rb-hero-slider .hs-slide.is-active .hs-in > *,
  html.qi-motion .rb-hero-split .container > *,
  html.qi-motion .section-head .eyebrow,
  html.qi-motion .section-head h1,
  html.qi-motion .section-head h2,
  html.qi-motion .section-head p {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  /* 关闭悬停位移，避免晕动 */
  html.qi-motion .rb .card,
  html.qi-motion .rb .card:hover,
  html.qi-motion .rb .card:hover img,
  html.qi-motion .rb .card:hover .ph,
  html.qi-motion .rb a:hover img,
  html.qi-motion .rb a:hover .ph {
    transform: none !important;
    transition: none !important;
  }
}
