/* ==========================================================================
   AgentFlux 动态视效升级（2026-10-11）
   --------------------------------------------------------------------------
   本文件只放**新增**的动效样式；theme.css 保持零改动，避免碰坏已有的
   整屏吸附 / 板块淡入淡出 / 导航发光 / 卡片悬停上浮 / 首屏归零。
   对应 1.md 的 M1~M5 五个模块。全部动效都做了 prefers-reduced-motion 降级。

   一个重要工程判断：
   1.md 的 M2 原方案用 ScrollTrigger pin 做「横向滚动 + 中心聚焦」。但本页是
   `html { scroll-snap-type: y mandatory }` + 每个板块固定 100svh —— 板块内部
   滚动距离为 0，pin 会与强制吸附互相打架（滚到一半松手会被吸回段首）。
   因此 M2 改为「板块内横向画廊 + 滚动驱动的中心聚焦 3D」，保住 2026-10-10
   用户定案的整屏分页契约。
   ========================================================================== */

/* ══════════════════════════════════════════════════════════════════════════
   M2 前置｜第 10 个板块「03A / REAL OUTPUTS」
   与另外 9 个板块同规格：固定一屏高 + 整屏吸附 + 参与 .is-current 淡入淡出。
   ══════════════════════════════════════════════════════════════════════════ */
.outputs {
  --output-card-w: clamp(200px, 20vw, 262px);
  height: 100svh;
  max-height: 100svh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: center;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background: transparent;
  padding: 76px 0 44px;
  transition: opacity .52s ease, transform .52s cubic-bezier(.2,.7,.2,1);
  will-change: opacity, transform;
}
.outputs:not(.is-current) { opacity: .55; transform: scale(.992); }
.outputs.is-current { opacity: 1; transform: scale(1); }

.outputs-head { margin-bottom: 18px; }
.outputs-head .section-title { margin-bottom: 12px; }
.outputs-head .section-lead { max-width: 640px; font-size: 14px; }

/* 自动横向滚动（2026-10-11 用户定案）：
   · 去掉电商/小红书切换按钮 → 一次展示全部产出
   · 去掉下方滑动条 → scrollbar 全部隐藏
   · 去掉左侧大留白 → 不再为"首卡居中"预留 calc 内边距，卡片从内容左边缘开始
   · 改为自动滚动 → 由 JS 递增 scrollLeft，鼠标移入暂停 */
.outputs-viewport {
  position: relative;
  width: 100%;
  padding: 8px 0;
  perspective: 1400px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  /* 隐藏滑动条（Firefox / IE / WebKit 三种写法都覆盖） */
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* 左右渐隐：卡片从左侧开始时不会被硬切出一条边，
     而是自然淡出 —— 跑马灯的标准处理，也让"不留大空位"不显得突兀。 */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 46px, #000 calc(100% - 46px), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 46px, #000 calc(100% - 46px), transparent 100%);
}
.outputs-viewport::-webkit-scrollbar { display: none; width: 0; height: 0; }

.outputs-track {
  display: flex;
  gap: 16px;
  width: max-content;
  padding: 4px 0;
}

.output-card {
  flex: 0 0 auto;
  width: var(--output-card-w);
  padding: 12px 12px 14px;
  border: 1px solid rgba(228, 234, 248, .92);
  border-radius: 24px;
  background: #fff;
  box-shadow: 0 20px 48px rgba(64, 87, 139, .12);
  scroll-snap-align: center;
  cursor: pointer;
  transform-style: preserve-3d;
  will-change: transform, opacity;
}
.output-card figure {
  position: relative;          /* 让 img 用绝对定位严格受限于这个盒子 */
  margin: 0;
  height: clamp(210px, 32svh, 310px);
  border-radius: 16px;
  background: linear-gradient(160deg, #f7faff, #eef4ff);
  overflow: hidden;
}
/* 早先用 display:grid + place-items:center 时，img 的 height:100% 百分比解析失真，
   实际排到 397px 被 overflow 切掉（等于裁图，违反 1.md 的 object-fit: contain）。
   改为绝对定位填满容器，contain 才能真的"整图完整放进格子"。 */
.output-card img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.output-card figcaption { padding: 12px 4px 0; }
.output-card-title {
  display: block;
  color: var(--ink);
  font-size: 14px;
  font-weight: 780;
  letter-spacing: -.02em;
}
.output-card-meta {
  display: block;
  margin-top: 5px;
  color: #7889a3;
  font-size: 11px;
  line-height: 1.6;
}
.output-card-status {
  display: inline-block;
  margin-top: 8px;
  padding: 3px 9px;
  border-radius: 99px;
  color: #1f7a5a;
  background: rgba(45, 168, 120, .12);
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .04em;
}

.outputs-foot {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-top: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.outputs-caption { margin: 0; color: #7892b8; font-size: 11px; font-weight: 760; letter-spacing: .06em; }

/* ══════════════════════════════════════════════════════════════════════════
   M1｜Hero 粒子汇聚（AgentFlux 字形光晕）
   --------------------------------------------------------------------------
   2026-10-11 用户定案：放弃「旋臂星云」方案，首页改用与尾页同一套
   粒子汇聚效果，位置沿用原星云所在区域（首屏右侧玻璃卡那一带）。
   色调 light（用户要求「调浅一点」），粒子在 HTML 标题背后成形，
   作为标题的光晕而不是独立的字。
   ══════════════════════════════════════════════════════════════════════════ */
/* theme.css 为旧的椭圆渲染设了 opacity: .48，会把粒子整体压暗；
   这里提到 1，亮度交给色调预设（TONES.light 的 alphaScale）控制。 */
.hero #hero-canvas { opacity: 1; }

/* 位置：画布铺满整个 hero，但粒子**只成形在右侧展示卡区域**
   （JS 侧 anchorSelector: '.hero-visual' 决定中心与尺寸）。
   早先只让画布覆盖右半幅（width: 58%），结果放大后的字形被画布右边界裁掉一角；
   改为整幅后，字形完整，四周环绕粒子也能自然铺开。
   左侧文案的可读性由 JS 的文字保护带保证（protectSelectors），
   不是靠缩小画布 —— 两者分工明确，避免"既想裁又不裁"的混乱。 */
#hero-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}
#hero-canvas.is-fallback { display: none; }

/* ── 删除 Hero 原有的装饰图形（2026-10-11 用户要求）──────────────────────
   用户标注：「背景的效果图形可以删掉了」。
   被删的三件（都在 theme.css 里，此处只覆盖不修改原文件）：
   1. .hero::before          右下那个大椭圆环 + 双层描边
   2. .visual-halo           右侧呼吸光晕（7s 缩放动画）
   3. .visual-ring           绕圈的椭圆环 + 白点 */
.hero::before { display: none; }
.visual-halo,
.visual-ring { display: none; }

/* ── 首页文字：一个字都不动（2026-10-11 用户要求）────────────────────────
   全程未对首页文字做任何样式干预（不加滤镜、不改字号/颜色/位置）。
   可读性靠两件事保证：
   ① 画布只覆盖右半幅（上面 #hero-canvas 的 inset）；
   ② JS 侧文字保护带（protectSelectors）让粒子避开标题与说明行。
   下面这条 z-index 只让文字压在画布之上，不改任何视觉属性。 */
.hero-content { position: relative; z-index: 2; }

/* ══════════════════════════════════════════════════════════════════════════
   M3｜DESIGN DECISION 人工审批状态机
   在现有 .gate-diagram 上叠一层 SVG 连线与数据包；不新增任何界面文案，
   保持 9 个板块的内容文案不变（1.md 的按钮方案因「不改文案」约束暂未加）。
   ══════════════════════════════════════════════════════════════════════════ */
.gate-flow {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}
.gate-flow path {
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
}
.gate-flow .gate-path-yes { stroke: #8fd0b6; }
.gate-flow .gate-path-no { stroke: #e0b4a4; }
.gate-flow .gate-packet-yes { fill: #2da878; }
.gate-flow .gate-packet-no { fill: #c47c65; }

/* 等待人工：中心节点的浅蓝脉冲（周期约 2.4s） */
.gate-node.center { transition: box-shadow .4s ease, border-color .4s ease; }
.gate-node.center.is-waiting {
  border-color: #5b9bf5;
  animation: gate-wait 2.4s ease-in-out infinite;
}
@keyframes gate-wait {
  0%, 100% { box-shadow: 0 0 0 8px rgba(88, 149, 244, .07), 0 14px 32px rgba(71, 117, 188, .14); }
  50% { box-shadow: 0 0 0 17px rgba(88, 149, 244, .15), 0 14px 34px rgba(71, 117, 188, .18); }
}
/* 采纳 / 打回分支的高亮反馈 */
.gate-branches div { transition: border-color .3s ease, box-shadow .3s ease, background .3s ease; }
.gate-branches .yes.is-lit {
  border-color: #62c39c;
  background: #f2fbf7;
  box-shadow: 0 6px 16px rgba(45, 168, 120, .14);
}
.gate-branches .no.is-lit {
  border-color: #dda58f;
  background: #fdf6f3;
  box-shadow: 0 6px 16px rgba(196, 124, 101, .14);
}

/* ══════════════════════════════════════════════════════════════════════════
   M4｜SYSTEM BOUNDARY 知识网络流动
   语义严格沿用现有 SVG：资料→任务 / 资料→Agent 是「只读关联」，
   任务→交付 / Agent→交付 是「生产路径」。不把资料直连交付。
   ══════════════════════════════════════════════════════════════════════════ */
.knowledge-graphic svg .kf-path { transition: opacity .3s ease; }
.knowledge-graphic svg .kf-node { transition: filter .3s ease; }
/* 悬停某节点时，淡化与它无关的连线与数据包 */
.knowledge-graphic svg.is-focusing .kf-path:not(.is-lit) { opacity: .18; }
.knowledge-graphic svg.is-focusing .kf-packet:not(.is-lit) { opacity: .12; }
.knowledge-graphic svg .kf-node.is-focus { filter: drop-shadow(0 0 7px rgba(67, 133, 237, .55)); }

/* ══════════════════════════════════════════════════════════════════════════
   M5｜Closing 粒子汇聚成 AgentFlux.（Canvas 2D）
   --------------------------------------------------------------------------
   2026-10-11 用户定案：
   · 与首页使用同一套效果（morph-particles.js），scale 1.2 → 放大 20%；
   · 四周加环绕粒子，避免画面太空；
   · 删除原 .closing-title（Agent_Flux_.）—— 它挡住了粒子效果。
   因此这里只剩：画布铺满 + 把副标题与按钮压到底部，把画面中央让给粒子。
   ══════════════════════════════════════════════════════════════════════════ */
.closing { position: relative; }
#closing-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  pointer-events: none;
}
#closing-canvas.is-fallback { display: none; }

/* 副标题与 CTA 压在粒子层之上，并整体下移：
   粒子字形在画布 44% 高度处成形（scale 1.2），
   若内容仍居中就会正好压在字形上 —— 用户反馈的"文字挡住效果"即此。
   改为底部对齐 + 加大下内边距，中央完整留给粒子。 */
.closing-inner {
  justify-content: flex-end;
  padding-bottom: 12svh;
}
.closing-inner, .closing footer { position: relative; z-index: 1; }
/* 浅色描边保证副标题在亮部依然可读（不改字号/颜色/位置） */
.closing-sub {
  filter: drop-shadow(0 2px 14px rgba(249, 251, 255, .85));
}

/* ══════════════════════════════════════════════════════════════════════════
   响应式：与 theme.css 的断点保持一致
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-height: 780px) {
  .outputs { padding: 66px 0 34px; }
  .outputs-head { margin-bottom: 12px; }
  .outputs-head .section-title { margin-bottom: 8px; }
  .outputs-head .section-lead { font-size: 13px; }
  .output-card figure { height: clamp(170px, 27svh, 240px); }
  .outputs-foot { margin-top: 8px; padding-top: 9px; }
}

/* 窄屏：取消整屏吸附（与 theme.css 的手机策略一致） */
@media (max-width: 760px) {
  /* 尾页在手机上必须给足高度：删掉标题后板块只剩 336px，
     粒子字形（画布 44% 高度处成形）会与底部副标题、CTA 压在一起。
     给定 74svh 后，字形落上部、内容沉底，两者不再重叠。 */
  .closing { min-height: 74svh; }
  .closing-inner { padding-bottom: 6svh; }

  .outputs {
    --output-card-w: min(62vw, 232px);
    height: auto;
    max-height: none;
    min-height: 0;
    overflow: visible;
    padding: 104px 0 56px;
  }
  .outputs:not(.is-current) { opacity: 1; transform: none; }
  .outputs-track { gap: 12px; }
  .output-card { border-radius: 20px; }
  .output-card figure { height: min(52vw, 300px); }
  .outputs-viewport { perspective: 800px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   尊重「减少动效」偏好：停掉持续动画，保留静态可读状态
   ══════════════════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: reduce) {
  .outputs { transition: none; opacity: 1; transform: none; }
  .outputs-viewport { perspective: none; }
  .output-card { transform: none !important; opacity: 1 !important; }
  .gate-node.center.is-waiting { animation: none; border-color: #84b0f5; }
  .gate-flow { display: none; }
  /* M1/M5 的粒子层在 reduced-motion 下各自只渲染静态一帧；
     首页文字不做任何样式干预（用户要求），故此处不再覆盖 filter。 */
  .knowledge-graphic svg .kf-packet { display: none; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Hero 动效参数面板（2026-10-11 新增）
   --------------------------------------------------------------------------
   用户要求：把首页粒子动效**所有可设置项**做成一排滑动条、拖动即时生效。
   当前常驻显示；调好之后的隐藏开关在 scripts/motion/hero-tuner.js 的
   DEFAULT_VISIBLE（也可用 index.html?tune=0 临时关闭）。
   样式全部写在 motion.css 末尾 —— theme.css 保持零改动。
   视觉沿用站点既有 Liquid Glass 语言（与 .top-nav 同族），不新增色值。
   ══════════════════════════════════════════════════════════════════════════ */
.motion-tuner {
  position: fixed;
  z-index: 130;
  left: 50%;
  bottom: 16px;
  transform: translateX(-50%);
  width: min(calc(100% - 32px), 1380px);
  padding: 10px 14px 8px;
  border: 1px solid rgba(255, 255, 255, .78);
  border-radius: 20px;
  background: rgba(255, 255, 255, .84);
  box-shadow: 0 18px 46px rgba(51, 80, 143, .18), inset 0 1px 0 rgba(255, 255, 255, .95);
  backdrop-filter: blur(22px) saturate(150%);
  color: var(--ink);
  -webkit-user-select: none;
  user-select: none;
}
.motion-tuner-head { display: flex; align-items: center; gap: 10px; }
.motion-tuner-title { flex: none; color: var(--blue); font-size: 11px; font-weight: 800; letter-spacing: .14em; white-space: nowrap; }
.motion-tuner-hint { overflow: hidden; color: var(--soft); font-size: 10px; text-overflow: ellipsis; white-space: nowrap; }
.motion-tuner-actions { display: flex; flex: none; gap: 6px; margin-left: auto; }
.motion-tuner-actions button {
  padding: 5px 11px;
  border: 1px solid rgba(55, 88, 147, .16);
  border-radius: 99px;
  color: #294778;
  background: rgba(255, 255, 255, .8);
  font: inherit;
  font-size: 10px;
  font-weight: 750;
  cursor: pointer;
  transition: background .18s, color .18s;
}
.motion-tuner-actions button:hover { color: #fff; background: var(--blue); }

/* 一排滑动条：横向排列不换行，超出宽度横向滚动（保持"一排"的形态） */
.motion-tuner-row {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  margin-top: 8px;
  padding-bottom: 6px;
  overflow-x: auto;
  scrollbar-width: thin;
}
.tuner-item { flex: 0 0 auto; width: 128px; }
.tuner-name {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
  color: var(--muted);
  font-size: 10px;
  font-weight: 700;
  white-space: nowrap;
}
.tuner-name b { color: var(--blue); font-variant-numeric: tabular-nums; }
.tuner-item input[type="range"] { display: block; width: 100%; height: 20px; margin: 3px 0 0; accent-color: var(--blue); cursor: pointer; }
.tuner-item input[type="range"]:disabled { cursor: not-allowed; opacity: .45; }
.tuner-chip {
  flex: 0 0 auto;
  padding: 5px 11px;
  border: 1px solid rgba(55, 88, 147, .16);
  border-radius: 99px;
  color: #526077;
  background: rgba(255, 255, 255, .72);
  font: inherit;
  font-size: 10px;
  font-weight: 750;
  white-space: nowrap;
  cursor: pointer;
  transition: background .18s, color .18s, border-color .18s;
}
.tuner-chip[aria-pressed="true"] { border-color: rgba(36, 104, 239, .34); color: #fff; background: var(--blue); }
.motion-tuner-json {
  width: 100%;
  height: 96px;
  margin-top: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  background: #fff;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 10px;
  line-height: 1.6;
  resize: vertical;
  -webkit-user-select: text;
  user-select: text;
}
@media (max-width: 760px) {
  .motion-tuner { bottom: 8px; width: calc(100% - 16px); padding: 8px 10px 6px; }
  .motion-tuner-hint { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .motion-tuner-actions button, .tuner-chip { transition: none; }
}
