/* ===========================================================================
   第一区块与页面背景的氛围特效
   ---------------------------------------------------------------------------
   独立文件，不并进 input.css —— 这样「不要特效了」只是把 index.html 里的
   两行引用删掉，不用动 git、不会和后续改动冲突。js/fx.js 同理。

   所有效果都只动 transform / opacity / filter，跑在合成层，不触发重排。

   每项效果由 <html> 上的 data-fx-* 开关控制，由 js/fx.js 在启动时统一打开。
   看着多此一举，但它是【逐项的关闭开关】：想停掉某一个效果，
   在 fx.js 的 FX 数组里划掉一行即可，不必去 CSS 里翻。
   =========================================================================== */

/* ---- A 鼠标视差 --------------------------------------------------------
   三层不同幅度：文案最浅、手机最深、气泡居中。
   变量由 js/lab-hero.js 每帧写入，CSS 只负责换算成位移。

   手机的 transform 归 main.js 所有（循环动画写在 .device 上），
   所以视差套在外面新加的 .fx-depth 上 —— 父子 transform 天然叠加，
   两边互不知情也不会打架。 */
.fx-depth { will-change: transform; }
[data-fx-parallax="on"] .enter__lead,
[data-fx-parallax="on"] .enter__cta {
  transform: translate3d(calc(var(--px, 0) * -7px), calc(var(--py, 0) * -5px), 0);
}
[data-fx-parallax="on"] .fx-depth {
  transform: translate3d(calc(var(--px, 0) * 16px), calc(var(--py, 0) * 11px), 0);
}

/* ---- C 氛围光 ----------------------------------------------------------
   六团环境光 + 一团跟着光标走的光斑。

   结构是【两层】的：外层 <i> 吃「指针视差 + 滚动收拢」，内层 <span> 吃
   自己的长周期漂移关键帧。一个元素上只能有一个 transform，两个效果要
   同时作用就必须分层 —— 第一版光的 transform 被关键帧占着，加不了别的。

   三组周期 26 / 41 / 33 / 37 / 29 / 47 秒两两互质，合起来永远不重复，
   不会像 GIF 那样露出接缝。 */
.fx-aura {
  position: absolute; inset: -14%;
  pointer-events: none;
  /* 0 而不是更高：与 .stage__gl 同层，靠 DOM 顺序落到画布后面。
     文案所在的 .enter__inner 是 z-10，永远压在光上面。 */
  z-index: 0;
  opacity: 0;
  transition: opacity 0.6s ease;
}
[data-fx-aura="on"] .fx-aura { opacity: 1; }

/* 外层：--depth 决定跟指针的幅度（越大越「近」），
   --sp 是首屏跑道的进度，随滚动把光往中心收并放大 —— 呼应「被吸进手机」。 */
.fx-aura i {
  position: absolute; inset: 0; display: block;
  transform:
    translate3d(
      calc(var(--px, 0) * var(--depth, 10) * 1px + var(--cx, 0) * var(--sp, 0) * 1px),
      calc(var(--py, 0) * var(--depth, 10) * 1px + var(--cy, 0) * var(--sp, 0) * 1px),
      0)
    scale(calc(1 + var(--sp, 0) * 0.28));
  will-change: transform;
}
.fx-aura span {
  position: absolute; display: block;
  border-radius: 50%;
  filter: blur(72px);
}
.fx-aura span { animation-play-state: paused; }
[data-fx-aura="on"] .fx-aura span { animation-play-state: running; }

.fx-aura .l1 { width: 30%; aspect-ratio: 1; left:  6%; top:    14%;
  background: radial-gradient(circle, rgba(194, 40, 64, calc(var(--a1, 0.30) * var(--gain, 1))), transparent 70%);
  animation: fxDriftA 26s ease-in-out infinite; }
.fx-aura .l2 { width: 26%; aspect-ratio: 1; right: 7%; bottom: 14%;
  background: radial-gradient(circle, rgba(216, 145, 236, calc(var(--a2, 0.34) * var(--gain, 1))), transparent 70%);
  animation: fxDriftB 41s ease-in-out infinite; }
.fx-aura .l3 { width: 34%; aspect-ratio: 1; left: 30%; bottom: -4%;
  background: radial-gradient(circle, rgba(216, 210, 164, calc(var(--a3, 0.55) * var(--gain, 1))), transparent 66%);
  animation: fxDriftC 33s ease-in-out infinite; }
.fx-aura .l4 { width: 22%; aspect-ratio: 1; right: 16%; top: 6%;
  background: radial-gradient(circle, rgba(251, 244, 237, calc(var(--a4, 0.75) * var(--gain, 1))), transparent 68%);
  animation: fxDriftA 37s ease-in-out infinite reverse; }
.fx-aura .l5 { width: 24%; aspect-ratio: 1; left: 18%; bottom: 6%;
  background: radial-gradient(circle, rgba(216, 145, 236, calc(var(--a5, 0.20) * var(--gain, 1))), transparent 70%);
  animation: fxDriftB 29s ease-in-out infinite; }
.fx-aura .l6 { width: 20%; aspect-ratio: 1; right: 30%; top: 34%;
  background: radial-gradient(circle, rgba(194, 40, 64, calc(var(--a6, 0.18) * var(--gain, 1))), transparent 72%);
  animation: fxDriftC 47s ease-in-out infinite reverse; }

/* 跟着光标的那一团：位置直接由 --mx/--my 写（js 里已做插值，不会粘手）。
   它不参与滚动收拢 —— 光标在哪它就在哪，跟着一起跑会显得失控。 */
.fx-spot {
  position: absolute; z-index: 0;   /* 同上：排在画布之前 = 在手机后面 */
  width: 30rem; height: 30rem;
  margin: -15rem 0 0 -15rem;
  left: var(--mx, 50%); top: var(--my, 50%);
  border-radius: 50%;
  pointer-events: none;
  filter: blur(78px);
  background: radial-gradient(circle, rgba(216, 145, 236, 0.26), rgba(194, 40, 64, 0.10) 46%, transparent 72%);
  opacity: 0;
  transition: opacity 0.5s ease;
}
[data-fx-aura="on"] .fx-spot { opacity: 1; }

@keyframes fxDriftA {
  0%,100% { transform: translate3d(0,0,0)        scale(1); }
  50%     { transform: translate3d(7%, 5%, 0)    scale(1.14); }
}
@keyframes fxDriftB {
  0%,100% { transform: translate3d(0,0,0)        scale(1.08); }
  50%     { transform: translate3d(-6%, -7%, 0)  scale(1); }
}
@keyframes fxDriftC {
  0%,100% { transform: translate3d(0,0,0)      scale(1); }
  50%     { transform: translate3d(4%, -6%, 0) scale(1.18); }
}

/* ---- E 信号波纹 -------------------------------------------------------
   从机身背后周期性扩散的发丝细环。发丝线本来就是全站的分隔语言，
   在这里换成会呼吸的形态，读作「正在连接」而不是新加了装饰。

   三环用同一段关键帧、错开三分之一周期，看起来是连续不断的一列。
   必须和氛围光同层（在手机后面）—— 环从机身「后面」荡开才对，
   压在屏幕上就成了贴纸。 */
.fx-rings {
  position: absolute; left: 50%; top: 50%; z-index: 0;
  width: 1px; height: 1px;
  pointer-events: none; opacity: 0;
  transition: opacity .6s ease;
}
[data-fx-rings="on"] .fx-rings { opacity: 1; }
.fx-ring {
  position: absolute; left: 50%; top: 50%;
  width: 46vmin; height: 46vmin; margin: -23vmin 0 0 -23vmin;
  border: 1px solid rgba(194, 40, 64, 0.5);
  border-radius: 50%;
  opacity: 0;
  animation: fxRing 7.5s cubic-bezier(0.25, 0.6, 0.3, 1) infinite;
}
.fx-ring:nth-child(2) { animation-delay: 2.5s; }
.fx-ring:nth-child(3) { animation-delay: 5s; border-color: rgba(216, 145, 236, 0.5); }
@keyframes fxRing {
  0%   { transform: scale(0.24); opacity: 0; }
  14%  { opacity: 0.5; }
  100% { transform: scale(1.55); opacity: 0; }
}

/* 创作四式的容器。

   这条规则原本写在「B 头像气泡」那一节里，删气泡时被整条带走了 ——
   包括下面这行跟着跑道进度淡出的。图标因此一路留到满屏，浮在一台正要
   吞掉视口的手机前面（业主截到的那一帧）。删一整节样式时要单独check
   里面有没有别的东西也依赖它。 */
.fx-orbit {
  position: absolute; inset: 0; pointer-events: none; z-index: 1;
  /* 放大过半时文案已经让位，图标也该收干净 —— 0.45 之前归零 */
  opacity: clamp(0, calc(1 - var(--sp, 0) * 2.2), 1);
}

/* ---- G 创作四式 -------------------------------------------------------
   写字 / 拍照 / 音乐 / 影像 —— 这四个词是 Features 里白纸黑字列举的
   「写字、拍照、音乐或影像，都可以在这里发布」。用的是站上自己的词汇，
   不是另编一套。

   线条图标而不是实心块：发丝线是全站的分隔语言，图标沿用同一种笔画，
   才不会像贴上去的第三方素材。而且它顺带回答了首屏最该回答的问题
   —— 这个 app 到底能拿来干什么。 */
.fx-craft {
  position: absolute;
  opacity: 0;
  color: rgba(87, 83, 74, 0.55);
}
.fx-craft svg { display: block; width: var(--d, 30px); height: var(--d, 30px); }
/* 宽屏落点：左右两条边栏，避开横跨全宽的标题与 CTA */
.fx-craft:nth-child(1) { left:  7%; top: 31%; --d: 34px; }
.fx-craft:nth-child(2) { left: 13%; top: 63%; --d: 30px; }
.fx-craft:nth-child(3) { left: 85%; top: 28%; --d: 32px; }
.fx-craft:nth-child(4) { left: 80%; top: 66%; --d: 30px; }
[data-fx-craft="on"] .fx-craft {
  animation: fxCraft var(--dur, 16s) ease-in-out var(--delay, 0s) infinite;
}
@keyframes fxCraft {
  0%,100% { opacity: 0; transform: translate3d(0, 12px, 0) scale(0.86) rotate(-4deg); }
  12%     { opacity: 1; transform: translate3d(0, 2px, 0)  scale(1) rotate(0deg); }
  80%     { opacity: 1; transform: translate3d(0, -14px, 0) scale(1) rotate(3deg); }
  93%     { opacity: 0; transform: translate3d(0, -22px, 0) scale(0.92) rotate(4deg); }
}

/* ---- I 连接线 ---------------------------------------------------------
   几条发丝弧线由外向内画进机身，画完即散。
   对应「不让地区与时间，成为沟通过程中的阻碍」—— 距离被跨过这件事，
   用一条线走完全程比任何文字都直接。全程没有一个字。

   和氛围光同层（手机后面）：线要「汇入」机身，压在屏幕上就成了划痕。 */
.fx-link {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none; opacity: 0;
  transition: opacity .6s ease;
}
[data-fx-link="on"] .fx-link { opacity: 1; }
.fx-link svg { width: 100%; height: 100%; display: block; }
.fx-link path {
  fill: none; stroke-width: 1.1; stroke-linecap: round;
  stroke-dasharray: 1000; stroke-dashoffset: 1000;
  opacity: 0;
  animation: fxLink 9s cubic-bezier(0.33, 0.9, 0.3, 1) infinite;
}
@keyframes fxLink {
  0%   { stroke-dashoffset: 1000; opacity: 0; }
  10%  { opacity: 0.85; }
  55%  { stroke-dashoffset: 0;    opacity: 0.85; }
  78%  { stroke-dashoffset: -560; opacity: 0; }
  100% { stroke-dashoffset: -560; opacity: 0; }
}

/* ---- H 光尘 -----------------------------------------------------------
   极小的颗粒缓慢上浮。和氛围光同一层，几乎零成本 ——
   没有模糊、没有图片，就是一堆 2–4px 的圆点。 */
.fx-dust { position: absolute; inset: 0; z-index: 0; pointer-events: none;
            opacity: 0; transition: opacity .8s ease; }
[data-fx-dust="on"] .fx-dust { opacity: 1; }
.fx-dust b {
  position: absolute; display: block;
  width: var(--d, 3px); height: var(--d, 3px);
  border-radius: 50%;
  background: rgba(87, 83, 74, 0.32);
  animation: fxDust var(--dur, 20s) linear var(--delay, 0s) infinite;
}
@keyframes fxDust {
  0%   { transform: translate3d(0, 0, 0);            opacity: 0; }
  12%  { opacity: 0.9; }
  78%  { opacity: 0.9; }
  100% { transform: translate3d(var(--dx, 10px), -46vh, 0); opacity: 0; }
}

/* ---- 跨区块的背景层 ---------------------------------------------------
   氛围光与连接线要一路铺到下载区之前。

   做法是一层 fixed 垫在 <body> 里，【不用算滚动范围】——
     · .section 没有自己的底色（透明），所以中间几个区块能透出来
     · .enter__pin 是 z-30 且铺了不透明的 bg-canvas，首屏自动挡住它
       （首屏有自己那一套光，在 pin 里面）
     · #download 与 footer 是不透明的 bg-ink-surface，尾部自动挡住
   于是它恰好只在「第二区块 → IG 条」那一段可见，正是要的范围。

   z-index 必须是 -1 而不是 0：定位元素（含 z-index:0）画在静态内容【之上】，
   用 0 会盖住正文。-1 让它落在 body 底色之上、所有内容之下。 */
.fx-page {
  position: fixed; inset: 0; z-index: -1;
  pointer-events: none;
  opacity: 0;
  transition: opacity .8s ease;
}
[data-fx-aura="on"] .fx-page,
[data-fx-link="on"] .fx-page { opacity: 1; }
.fx-page .fx-aura,
.fx-page .fx-link { opacity: 0; }
[data-fx-aura="on"] .fx-page .fx-aura { opacity: 1; }
[data-fx-link="on"] .fx-page .fx-link { opacity: 0.50; }

/* 页面层的线【磨成柔光带】，不再是清晰的线。

   业主反馈背景的线太抢眼、和正文重叠。第一反应是让线走边栏躲开文字，
   但实测正文在 1440 下横跨视口的 11.7%–88.3%，两侧各只剩 12% ——
   根本没有边栏可躲。

   所以改的是线【本身的性质】：清晰的 1px 边缘才会被眼睛抓住并当成图形，
   加了模糊之后同样的路径读作一道光。笔画同时加粗（模糊会把细线吃掉）。

   参数是量出来的，不是拍的。两个判据缺一不可：
     · 峰值对比 —— 边缘有多跳，决定它抢不抢眼。平均值没用，线只覆盖
       很少的像素，平均几乎不动
     · 视觉粗细 —— 模糊会把笔画摊开，看上去的宽度是 笔画 + 2×模糊，
       光看 stroke-width 会误判

       blur 0 / 笔画 1.1 / 0.85   →  峰值 141   太抢，像图形
       blur 7 / 笔画 2.6 / 0.42   →  峰值  11   矫枉过正
       blur 5 / 笔画 3.4 / 0.60   →  22px      柔了但太粗
       blur 3.6/ 笔画 2.4 / 0.58  →  17px 峰值 24   ← 只降模糊反而更抢：
       blur 2.8/ 笔画 1.8 / 0.55  →  15px 峰值 23      笔画还粗，能量集中了
       blur 2 / 笔画 1.2 / 0.50   →   8px 峰值 15   ← 定稿：细了三分之二，
                                                      抢眼程度没上去
   首屏那几条不动 —— 它们汇向手机，那里没有正文。 */
.fx-page .fx-link { filter: blur(2px); }
.fx-page .fx-link path { stroke-width: 1.2; }
/* 页面层的光不参与首屏那条跑道的收拢：--sp 只对首屏有意义，
   一路铺下去的光跟着它收会在滚过第二区块时突然缩成一团。 */
.fx-page .fx-aura i { --sp: 0; }

/* 页面层的光【比首屏更浓】。
   首屏有手机和大标题当视觉重心，光只需要垫底；第二区块之后只有文字，
   同样的浓度就显得空。

   加浓不能用 filter: opacity() —— 那个只能让东西更透明，大于 1 会被
   夹到 1，实测 1.5× / 2.0× / 2.6× 三档数字完全一样。必须动渐变本身，
   所以每团光的透明度都参数化成 --a1..--a6，这里统一乘一个 --gain。 */
.fx-page .fx-aura { --gain: 1.85; }

@media (max-width: 900px) {
  .fx-dust { display: none; }
  /* 创作四式在手机上保留，但要重新排位 —— 宽屏那套落点是按左右边栏算的，
     窄屏没有边栏，只有机身两侧那两条窄缝。
     实测 390×844：机身占 x 109–281，标题在 y 155–257，CTA 在 y 670 以下，
     图标只能落在 x<28% 或 x>72%、y 32%–80% 这个区间里。
     尺寸也收到 26–28px —— 30px 以上在那条缝里显得挤。 */
  .fx-craft:nth-child(1) { left:  6%; top: 34%; --d: 28px; }
  .fx-craft:nth-child(2) { left: 13%; top: 62%; --d: 26px; }
  .fx-craft:nth-child(3) { left: 78%; top: 31%; --d: 28px; }
  .fx-craft:nth-child(4) { left: 84%; top: 60%; --d: 26px; }
  .fx-aura .l4, .fx-aura .l5, .fx-aura .l6 { display: none; }
  .fx-aura span { filter: blur(44px); }
  .fx-spot { width: 22rem; height: 22rem; margin: -11rem 0 0 -11rem; filter: blur(48px); }
}
@media (prefers-reduced-motion: reduce) {
  .fx-aura span, .fx-ring, .fx-craft, .fx-link path, .fx-dust b { animation: none !important; }
  .fx-aura i, .fx-spot { transform: none !important; }
  .fx-craft { opacity: .85; }
  .fx-link path { stroke-dashoffset: 0; opacity: .5; }
  [data-fx-parallax="on"] .enter__lead,
  [data-fx-parallax="on"] .enter__cta,
  [data-fx-parallax="on"] .fx-depth,
  [data-fx-parallax="on"] .fx-aura { transform: none; }
}
