/* ============================================================================
   landing.css — Neo 功能展示落地页（Overhaul）· **首页专属**
   token + 通用基元已抽到 assets/neo-tokens.css（本页在它之后引入）。
   这里只留首页专属：Hero 舞台/卡/能力动画/模块栅格/价格/API 引子。
   不改 assets/base.css（recharge.html 继续用它）。
   ============================================================================ */

/* Hero 卡面专属 token（只服务 .face--*，不抽走） */
:root, html[data-theme="light"] {
  --card-edge: oklch(0 0 0 / .10);
  /* 焦点环拆成「颜色 + 粗细」两个值：轮盘在转、焦点每秒换一张卡，
     环的显隐必须能逐帧淡 —— outline / box-shadow 都做不到。 */
  --focal-ring-c: rgba(224, 154, 46, .55);
  --focal-ring-w: 1.5px;
  --plate: rgba(14, 18, 22, .82);
  --plate-ink: #F5F3EE;
}
html[data-theme="dark"] {
  --card-edge: oklch(1 0 0 / .14);
  --focal-ring-c: rgba(239, 168, 60, .78);
  --focal-ring-w: 2px;
  --plate: rgba(14, 18, 22, .82);
  --plate-ink: #F5F3EE;
}

/* 价格区块内的独立 CTA（设计 §6.4）：导航 CTA 落在 #price，再从这里去充值页 */
.price-more { margin-top: 24px; }

/* 常规卡阴影：按规格 §2.5 的使用表，--sh-1 用于常规卡面 */
.plan, .logic, .deai { box-shadow: var(--sh-1); }

/* ---------- 6 · HERO ---------- */
.hero { padding-block-start: 64px; }
.hero__copy { margin-bottom: 8px; }
.hero__lead { max-width: 56ch; }
.hero__row { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-top: 22px; flex-wrap: wrap; }

/* ---------- 下载 CTA（首屏 + 模块 01 共用 · 2026-11-09） ----------
   ★★ 两颗按钮指向**两个不同的安装包**，不是同一份：
        首屏（Hero）        → releases/neo/1.0.8/NEO-Setup-1.0.8.exe   主客户端
        模块 01 字标下方     → releases/neo/2.1.0/NEO-Setup-2.1.0.exe   NEO Design 桌面端
      所以两颗的文案必须能区分（「下载 Windows 客户端」/「下载 NEO Design 客户端」）；
      别为了「统一」把其中一颗改成另一颗的地址或文案——那是两个产品。
   ★ 外壳仍用全局 .btn.btn--primary（和导航那颗 .btn--pill 同一套观感），
     这里只补三样：竖列排布（含窄屏换行）、图标、右侧版本/体积说明。
   ★ 颜色全部走令牌：.btn--primary 给 --accent/--on-accent，说明文字用 --ink-3
     （浅色 6.35:1 / 深色 7.36:1，均过 AA）。 */
.dlcta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;          /* 换行时纵向 10px、同一行时横向 14px */
  margin-top: 20px;
}
/* 可点区域不低于 44px：.btn 的 11px 内边距 + 20px 行高 ≈ 42px，这里补 2px */
.dlcta__btn { min-height: 44px; }

/* 首屏那颗下面就是作品墙（.stage 自带 0 上边距），窄屏上说明文字会与卡片几乎贴住
   ⇒ 单独给首屏补 14px 下边距。模块 01 那颗不需要：它上面有 sec__head 的 40px。 */
.hero .dlcta { margin-bottom: 14px; }

.dlcta__icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;    /* 跟随 --on-accent，深浅主题都不用改 */
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.dlcta__note {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: .06em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

/* ★ 2026-10-13：原「扇面 / 横排」分段控件（.seg / .seg__btn）与窄屏横排的
   scroll-snap 规则随横排一起删除 —— HTML 里那个控件早就不在了，CSS 是死代码。 */

/* 舞台 = 横向滚动容器（越界元素只有落在 overflow-x:auto 且真溢出时才被门禁豁免） */
.stage {
  --cw: 164px; --ch: 219px; --stage-h: 336px;
  position: relative;
  overflow-x: auto; overflow-y: hidden;
  scrollbar-width: none; -ms-overflow-style: none;
  overscroll-behavior-x: contain;
  padding: 26px 0 56px;
}
.stage::-webkit-scrollbar { display: none; }
@media (min-width: 1200px) {
  .stage { --cw: 200px; --ch: 267px; --stage-h: 470px; padding: 28px 0 72px; }
}

/* 整墙缩放贴合：--wall-scale 由 JS 写入（CSS 不能做 length/length 除法） */
.wall { position: relative; width: 100%; height: var(--stage-h); transform: scale(var(--wall-scale, 1)); transform-origin: top center; transition: transform .3s var(--ease-soft); }
.track { position: absolute; inset: 0; }
/* ★★ 连续旋转期间卡片姿态是**逐帧写入**的 ⇒ 必须关掉 .card 的 transform 过渡。
   留着会「追帧」（每帧都给一个 0.26s 过渡重设目标），弧端换位也会被它拖成一段拖影。
   反过来，一旦停下（hover / focus / 翻转 / reduced-motion）就摘掉这个类，
   hover 抬升才恢复成「滑上去」而不是「啪」地跳一下。 */
.stage.is-spin .card { transition: none; }

/* 卡片：外层 = 布局姿态（perspective → translate3d → rotateZ → scale）。
   ★ 横向位置全走 transform（--tx）：left 恒为 50% ⇒ 槽位 p=0 的卡永远落在舞台正中，
     轮盘旋转就是「同一个 left、不同的 --tx」逐帧写入。 */
.card {
  position: absolute; left: 50%; top: 0;
  width: var(--cw); height: var(--ch);
  margin-left: calc(var(--cw) / -2);
  border-radius: var(--r-xl);
  cursor: pointer;
  transform:
    perspective(1400px)
    translate3d(var(--tx, 0px), calc(var(--ty, 0px) + var(--hover-ty, 0px)), var(--tz, 0px))
    rotateZ(var(--rz, 0deg))
    scale(calc(var(--s, 1) * var(--hover-s, 1)));
  filter: var(--card-filter, none);
  opacity: var(--op, 1);
  z-index: var(--z, 1);
  transition: transform .26s var(--ease-out), filter .26s var(--ease-out), opacity .26s var(--ease-out);
}
.card:hover, .card:focus-visible {
  --hover-ty: -16px; --hover-s: 1.03;
  filter: none; opacity: 1;
  z-index: 999;
  box-shadow: var(--sh-3);        /* 规格 §4.4：悬停用 --sh-3 */
}
.card:hover .face--front, .card:focus-visible .face--front { border-color: var(--accent-line); }
/* 卡面 inset 双色环：外 outline 在 3D 下可能被裁，内描边永不被裁 */
.card:focus-visible .face--front { box-shadow: inset 0 0 0 2px var(--plate), inset 0 0 0 4px var(--accent); }
.card.is-flipped { z-index: 999; }
/* 焦点环：一道克制的琥珀描边（不用零偏移 box-shadow 辉光 —— impeccable 的 dark-glow 会判红）
   + 规格 §2.5 指定给「Hero 焦点卡」的 --sh-4。
   ★★ 做成**独立伪元素 + opacity: var(--focal)**，而不是 .is-focal 上的 outline/box-shadow：
     轮盘在转、焦点每秒换一张卡，outline 与 box-shadow 都没法淡入淡出，直接切会「跳」；
     伪元素可以逐帧淡，读起来就是高亮沿着扇面滑过去。
   ★ pointer-events:none 是必须的：伪元素比卡大 6px，会替卡片多接住一圈点击。 */
.card::after {
  content: ""; position: absolute; inset: -6px;
  border-radius: calc(var(--r-xl) + 6px);
  box-shadow: inset 0 0 0 var(--focal-ring-w) var(--focal-ring-c), var(--sh-4);
  opacity: var(--focal, 0); pointer-events: none;
}

.card__inner {
  position: absolute; inset: 0; transform-style: preserve-3d;
  transform: perspective(1200px) rotateY(var(--flip, 0deg));
  transition: transform .52s var(--ease-inout);
}
.card.is-flipped .card__inner { --flip: 180deg; }

.face {
  position: absolute; inset: 0; border-radius: var(--r-xl); overflow: hidden;
  border: 1px solid var(--line-soft);
  backface-visibility: hidden; -webkit-backface-visibility: hidden;
}
.face--back { transform: rotateY(180deg); }

/* 边缘压暗：由 .card 的 filter brightness() 表达（见 --card-filter）。
   不用独立覆盖层——不透明覆盖层会被 impeccable 判为 text-occlusion，且 filter 加在 .card
   上不会压平 .card__inner 自带的 3D 翻转上下文。 */

/* 正面：色块 + 深色实底标签条。
   ★ 扇面态每张卡的横向地盘 ≈ 视口宽 ÷ 16（1440 下 ≈90px），与重叠多少无关 ——
     所以静态扇面里只放「序号 + 2–4 字短名」，且必须贴到**远离圆心**的那一侧
     （左半区靠左 / 右半区靠右），否则会被更靠中心的邻居压住。
     完整中/英风格名只在「焦点卡」与「hover / focus」时出现（见下方 .is-fan 规则）。 */
.face--front { background: oklch(0.64 0.10 var(--h, 255)); }
/* 材质内描边：极细、非渐变（双主题各一份；深色态是浅描边，不是黑） */
.face--front::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--card-edge); pointer-events: none;
}
/* 作品图：铺满卡面。源图是 2:3（1024×1536），用 cover 裁成卡片的 3:4。
   ★ 不加 filter / opacity —— 会压平 .card__inner 的 3D 翻转上下文。 */
.fp__img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: center; pointer-events: none; z-index: 0;
}
/* 卡面层级：作品图(0) < 材质内描边与焦点环(1) < 文字标签(2)。
   显式声明是因为图是 .face--front 的子元素，会盖住同为伪元素的 ::before 描边。 */
.face--front::before { z-index: 1; }
.face--front::after { z-index: 1; }
/* 焦点卡：一道克制的琥珀内描边（外环在 .card::after 上），同样跟着 --focal 淡 */
.face--front::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 0 0 1.5px var(--accent-line); pointer-events: none;
  opacity: var(--focal, 0);
}
.fp__mini, .fp__full { position: absolute; z-index: 2; }
/* ★ 2026-10-17：名字底板按需求删除（原为 --plate: rgba(14,18,22,.82) 的近黑圆角底）。
   去掉底板后白字直接压在作品图上 ⇒ 可读性全靠**多层投影**兜底。
   ★★ 这里的 text-shadow 不是装饰，是功能，别当冗余删掉。
   ★★ contrast.mjs 会对这几条报「不达标」：它只读 backgroundColor、看不见投影也看不见图片，
     量到的是「白字 vs .face--front 的色相底」≈2.4:1。那是**尺子的口径限制**，不是渲染实况。 */
.fp__mini, .fp__full {
  background: none; color: #FFFDF8;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; line-height: 1.3;
  /* ★★ 这不是装饰，是功能：底板没了以后，可读性全靠这三层投影（含一层 0 偏移的光晕）。
     去掉任意一层，浅色作品图上的名字就会糊。 */
  text-shadow: 0 0 3px rgba(0, 0, 0, .95), 0 1px 4px rgba(0, 0, 0, .85), 0 2px 12px rgba(0, 0, 0, .6);
}
.fp__full {
  left: 14px; right: 14px; bottom: 14px; padding: 9px 11px;
  display: flex; flex-direction: column; gap: 2px;
}
.fp__zh { font-family: var(--font-body); font-size: 15px; font-weight: 600; line-height: 1.3; letter-spacing: 0; }
.fp__en { font-size: 11px; letter-spacing: .02em; opacity: .95; }
.fp__mini {
  bottom: 14px; left: 14px; padding: 4px 6px; display: none; border-radius: 3px;
  flex-direction: column; gap: 0; align-items: flex-start;
}
.card[data-side="right"] .fp__mini { left: auto; right: 14px; align-items: flex-end; }
.fp__mini-n { font-size: 11px; line-height: 1.15; letter-spacing: 0; opacity: .88; }
.fp__mini-t { font-family: var(--font-body); font-size: 12px; font-weight: 500; line-height: 1.2; white-space: nowrap; letter-spacing: 0; }

/* 紧凑态：扇面 + 非焦点卡 + 未 hover/focus → 只显示短名标签。
   ★ 用 display 硬切而不是交叉淡入：两块底板同锚在左下角，半透明叠加会把两行字糊在一起。
     .is-focal 的切换点取在两张候选卡**等距**的那一刻（|p| = 0.5），
     所以不会有「两张卡都半亮」的中间态。 */
.stage.is-fan .card .fp__full { display: none; }
.stage.is-fan .card .fp__mini { display: flex; }
.stage.is-fan .card.is-focal .fp__full,
.stage.is-fan .card:hover .fp__full,
.stage.is-fan .card:focus-visible .fp__full { display: flex; }
.stage.is-fan .card.is-focal .fp__mini,
.stage.is-fan .card:hover .fp__mini,
.stage.is-fan .card:focus-visible .fp__mini { display: none; }

/* 背面：有意义，非空白 */
.face--back {
  background: var(--surface-2); padding: 16px; display: flex; flex-direction: column;
  /* 未翻转时视觉隐藏（与 inert/aria-hidden 一致）：翻回时延迟到 520ms 旋转结束再隐藏 */
  visibility: hidden; transition: visibility 0s linear .52s;
}
.card.is-flipped .face--back { visibility: visible; transition-delay: 0s; }
.face--back::before { content: ""; position: absolute; inset: 0 0 auto; height: 1px; background: var(--accent-line); }
.face--back::after {
  content: attr(data-wm); position: absolute; right: 6px; bottom: -14px;
  font-family: var(--font-display); font-size: 96px; line-height: 1; font-weight: 600;
  color: var(--line); pointer-events: none; user-select: none;
}
.back__hd { display: flex; flex-direction: column; gap: 2px; }
.back__zh { font-family: var(--font-display); font-size: 19px; font-weight: 600; line-height: 1.25; color: var(--ink); }
.back__en { font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; color: var(--ink-3); }
.back__desc { margin-top: 10px; font-size: 13px; line-height: 1.6; color: var(--ink-2); }
.back__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.back__tags li { padding: 3px 8px; border-radius: var(--r-xs); background: var(--well); color: var(--ink-3); font-size: 11px; }
.back__spec { margin-top: auto; padding-top: 10px; font-family: var(--font-mono); font-size: 11px; color: var(--ink-3); }
.back__link { margin-top: 6px; font-size: 13px; font-weight: 600; color: var(--accent-ink); }
.back__link:hover { color: var(--accent-hover); text-decoration: underline; text-underline-offset: 3px; }

/* ---------- 7 · 能力带 ----------
   UX 规格 §C4 裁决：放弃自动流动 marquee（动效风险 + impeccable 的 marquee 反模式），
   改为单行、可横向滚动的静态关键词带。 */
.band { background: var(--surface); border-block: 1px solid var(--line); }
.band__scroller { overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain; }
.band__scroller::-webkit-scrollbar { display: none; }
.band__track { display: flex; width: max-content; }
.band__item {
  display: inline-flex; align-items: center; padding: 18px 22px;
  border-inline-start: 1px solid var(--line);
  font-family: var(--font-mono); font-size: 13px; letter-spacing: .04em; color: var(--ink-3); white-space: nowrap;
}
.band__item:first-child { border-inline-start: 0; }

/* ---------- 8 · 模块 01 · AI 生图 ---------- */
/* 舞台：sticky + 滚动推进。前 30% 保持平铺（留时间看清 24 格），之后整片缩小（镜头拉远）。
   ★★ 类名必须是 .sstage 而不是 .stage —— Hero 的扇面/横排舞台已经占用了 .stage
     （本文件 §6 顶部）。同名时后定义者覆盖，`height:260vh` 会直接加到 Hero 舞台上，
     把首屏撑成 2.6 屏高、且**零报错**。这是本项目反复栽过的「类名撞车」型静默故障。 */
.sstage { position: relative; height: 260vh; margin-top: 8px; }
/* ≥1200：向两侧各外扩 64px 抵消 .wrap 的 padding ⇒ 24 格铺得更开（只在这一档外扩，
   窄屏外扩会顶出视口触发横向溢出，verify.mjs 会红） */
@media (min-width: 1200px) { .sstage { margin-inline: -64px; } }
.sstage__pin { position: sticky; top: 0; height: 100vh; display: grid; place-items: center; overflow: hidden; }
.sstage__bg {
  position: absolute; inset: 0; pointer-events: none;
  opacity: calc(.16 + var(--k, 0) * .5);
  background-image:
    linear-gradient(var(--line) 1px, transparent 1px),
    linear-gradient(90deg, var(--line) 1px, transparent 1px);
  background-size: 72px 72px;
  -webkit-mask-image: radial-gradient(72% 62% at 50% 50%, #000 20%, transparent 100%);
  mask-image: radial-gradient(72% 62% at 50% 50%, #000 20%, transparent 100%);
}
.sstage__glow {
  position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(58% 52% at 50% 46%, var(--accent-soft), transparent 72%);
  opacity: calc(.45 + var(--k, 0) * .7);
}

/* 网格本体：24 格连续平铺（8 列 × 3 行）。
   ★ 整片一起缩放 ⇒ transform 挂在父层，子元素不动、无重排、不抖。 */
.chips {
  position: relative; z-index: 1;
  width: 100%; max-width: 1380px; padding: 0 24px;
  display: grid; grid-template-columns: repeat(8, minmax(0, 1fr));
  gap: 10px;
  transform: scale(var(--s, 1));
  transform-origin: center center;
  will-change: transform;
}
@media (max-width: 1100px) { .chips { grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 9px; } }
@media (max-width: 720px)  { .chips { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; } }

/* 分组壳与组头：**不参与视觉**，只留语义给屏幕阅读器。
   ★ 这是「平铺」与「分组」的调和点：24 格视觉上连续，DOM 里仍有 5 个 role=group 的语义组。
   display:contents 让 .stylegroup / .stylegroup__grid 不产生盒子 ⇒ .chipbtn 直接参与 .chips 的 grid。 */
.stylegroup { display: contents; }
.stylegroup__grid { display: contents; }
.stylegroup__hd {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* 单格：真图 + 底部名称条 */
.chipbtn {
  position: relative; display: block; overflow: hidden; padding: 0;
  aspect-ratio: 3 / 4; border-radius: 12px;
  border: 1px solid var(--line); background: var(--surface-2); box-shadow: var(--sh-1);
  cursor: pointer; text-align: start;
  transition: box-shadow .3s var(--ease-out), border-color .2s var(--ease-out);
}
.chipbtn:hover { box-shadow: var(--sh-3); border-color: var(--accent-line); }
.chipbtn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.chipbtn__img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* 名称条：压在卡片底部。
   ★★ 底必须是**不透明的 background-color**，不能只用 background-image 渐变 ——
     contrast.mjs 的 bgOf() 只读 backgroundColor（不解析渐变），用渐变会让它一路往上
     找到 .chipbtn 的浅色底，把白字算成 1.15:1（需 4.5）。实测踩过。 */
.chipbtn__zh {
  position: absolute; left: 0; right: 0; bottom: 0; padding: 10px 8px 6px;
  background-color: rgba(8, 10, 14, .86);
  color: #fff; font-size: 11.5px; font-weight: 600; line-height: 1.25;
}
.chipbtn[aria-pressed="true"] { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-line), var(--sh-2); }
/* 无图风格兜底（当前 0 个）：色相底 + SPEC 字样 */
.chipbtn__spec { display: none; }
.chipbtn[data-spec] { background: oklch(0.62 0.11 var(--h, 255)); }
.chipbtn[data-spec]::before {
  content: "SPEC"; position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: .12em; color: rgba(255,255,255,.9);
}

/* 提示词补全卡：改版后独立于网格（原来挂在右栏里），限宽居中 */
.gen { max-width: 560px; margin: 48px auto 0; }
.specrow { justify-content: center; margin-top: 20px; }

.anim { position: relative; }
.anim__cap { font-size: 13px; line-height: 1.5; color: var(--ink-3); margin-bottom: 12px; }

/* 生成卡（紧凑）：caption + 种子行 + 3 条「补全尾巴」。
   ★ #genSeed 有语义（"补全这句话"指的就是它），**不加 aria-hidden**；仅闪烁 caret 是装饰。
   ★ 3 条尾巴只留补全部分，去掉重复的种子词前缀（现状种子词出现 4 次 → 现为 1 次）。 */
.gen {
  display: grid; gap: 10px;
  padding: 14px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
}
.gen__cap { font-size: 13px; line-height: 1.5; color: var(--ink-3); }
.gen__input {
  display: flex; align-items: center; gap: 2px; min-height: 44px; padding: 0 14px;
  background: var(--well); border: 1px solid var(--line); border-radius: var(--r-sm);
  font-size: 15px; color: var(--ink);
}
.gen__caret { width: 2px; height: 20px; background: var(--accent); animation: blink 1s steps(1) infinite; }
@keyframes blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
.gen__tails { display: flex; flex-direction: column; gap: 8px; }
.gen__tail {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-radius: var(--r-sm);
  background: var(--surface-2); color: var(--ink-2); font-size: 14px; line-height: 1.5;
}
.gen__tail:first-child { background: var(--accent-soft); box-shadow: inset 0 0 0 1px var(--accent-line); }
.gen__tail svg {
  flex: none; width: 16px; height: 16px; color: var(--accent-ink);
  fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}
/* 补全块淡入（select 替换文本时；reduced-motion 下由 neo-tokens.css 关断） */
#genSeed, #genTails { transition: opacity .15s var(--ease-out); }

.specrow { display: flex; flex-wrap: wrap; gap: 8px; }
.specrow li {
  padding: 6px 12px; border-radius: var(--r-pill); border: 1px solid var(--line);
  background: var(--surface); font-family: var(--font-mono); font-size: 12px; letter-spacing: .03em; color: var(--ink-3);
}

/* ---------- 9b · 模块 02 · Part C WorkBuddy 能力带（原真实截图带，已替换） ----------
   ★ 三个标识全部真实来源（见 index.html 注释），没有一个是画出来的；图只有 256px 见方，
     72px 显示 ⇒ 用 webp 而非原 PNG（420/477KB → 13/21KB），门禁的图片检查仍按真实宽高断言。
   ★ 自包含：所有选择器都在 .wb 子树内；删掉本块 + index.html 的 <div class="wb"> 即无副作用。 */
.wb { margin-top: 40px; }
.wb__hd { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 20px; }
.wb__kicker { font-family: var(--font-mono); font-size: 11px; letter-spacing: .14em; color: var(--accent-ink); }
.wb__title { font-size: 15px; font-weight: 600; color: var(--ink-2); }
.wb__grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
@media (max-width: 899px) { .wb__grid { grid-template-columns: minmax(0, 1fr); } }
.wb__card { padding: 24px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
/* logo 是方形图：--r-lg 的一半会显得太圆，取 16px 与第三张 SVG 自带的 22% 圆角对齐 */
.wb__logo { display: block; width: 72px; height: 72px; border-radius: 16px; object-fit: cover; }
/* 第三张是矢量品牌标：自带圆角与描边，不能再叠 --well 底（会露出方形底色） */
.wb__logo--mark { object-fit: contain; background: none; }
.wb__kind { display: block; margin-top: 16px; font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; color: var(--ink-3); }
.wb__name { display: block; margin-top: 6px; font-size: 17px; font-weight: 700; color: var(--ink); }
.wb__desc { display: block; margin-top: 8px; font-size: 14px; line-height: 1.65; color: var(--ink-3); }

/* ---------- 10 · 模块 03 · 超级编导 ---------- */
.logic-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
@media (max-width: 899px) { .logic-grid { grid-template-columns: minmax(0, 1fr); } }
.logic { position: relative; display: flex; flex-direction: column; padding: 32px 28px 40px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; }
/* ★ 原 .logic::after 的 64px 幽灵序号已移除：
     它是按占位标题「核心逻辑」（4 字）留的位；换成真实标题（9 字 / 30px ≈ 270px）后，
     在 1024–1440 三栏下实测都会压到标题字身上（1440 下重叠约 18px）。
     序号信息由 h3 里的 .logic__num 承载，不需要再来一份装饰。 */
.logic .logic__num { font-family: var(--font-mono); font-size: .58em; color: var(--accent-ink); margin-inline-end: .5em; letter-spacing: .04em; }
.logic__body { margin-top: 14px; font-size: 15px; line-height: 1.8; color: var(--ink-3); }
/* 证据行：每条核心逻辑末尾给一条可核验的事实（数字取自专家包，可当场打开核对）
   margin-top:auto ⇒ 三张卡正文长短不一时，证据行仍对齐在同一条基线 */
.logic__evi {
  margin-top: auto; padding-top: 14px; border-top: 1px solid var(--line-soft);
  font-family: var(--font-mono); font-size: 12px; line-height: 1.6;
  letter-spacing: .02em; color: var(--accent-ink);
}
.logic__evi::before { content: ""; display: block; height: 18px; }

.statband { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 20px; margin-top: 40px; }
@media (max-width: 1023px) { .statband { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .statband { grid-template-columns: minmax(0, 1fr); } }
/* 4 列后每列只剩 ~270px：数字与单位改上下排，横排会挤成两行 */
.stat { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 24px 26px; background: var(--surface-2); border-radius: var(--r-lg); }
.stat__num { font-family: var(--font-display); font-size: clamp(38px, 4.4vw, 56px); line-height: 1; font-weight: 600; color: var(--ink); }
.stat__unit { font-family: var(--font-mono); font-size: 13px; line-height: 1.5; letter-spacing: .04em; color: var(--ink-3); }

.deai { margin-top: 40px; padding: 28px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
/* 两张证据卡连排时收窄间距 */
.deai + .deai { margin-top: 24px; }
.deai__grid { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 24px; align-items: center; }
@media (max-width: 767px) { .deai__grid { grid-template-columns: minmax(0, 1fr); } .deai__mid { align-items: flex-start; } }
.deai__h { font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; color: var(--ink-3); margin-bottom: 10px; }
.deai__text { font-size: 15px; line-height: 1.85; color: var(--ink-2); }
.deai mark {
  color: var(--ink);
  text-decoration: underline; text-decoration-style: wavy; text-decoration-color: var(--danger);
  text-decoration-thickness: 1.5px; text-underline-offset: 4px;
  transition: text-decoration-color .3s var(--ease-out);
}
.deai__col--out .deai__text { color: var(--ink); }
/* ★ 审核后下划线由「红=有问题」转「绿=已处理」，**不隐藏**：
   标记本身就是「标出套话」这个承诺的证据，藏掉等于把证据抹了（旧版是 transparent）。 */
.deai.is-done mark { text-decoration-color: var(--ok); }
.deai__mid { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.deai__stat {
  margin: 0; font-family: var(--font-mono); font-size: 12px; line-height: 1.8;
  letter-spacing: .02em; color: var(--accent-ink); text-align: center;
  font-variant-numeric: tabular-nums;
}
.deai__why { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--line-soft); }
.deai__list { margin: 0; padding-left: 1.4em; }
.deai__list li { font-size: 14px; line-height: 1.75; color: var(--ink-2); }
.deai__list li + li { margin-top: 6px; }
.deai__list li::marker { color: var(--accent-ink); font-weight: 700; }
.deai__list b { color: var(--ink); font-weight: 600; }

/* ---------- 10c · 边界（我们做 / 我们不做） ---------- */
.bounds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; margin-top: 40px; }
@media (max-width: 767px) { .bounds { grid-template-columns: minmax(0, 1fr); } }
.bounds__box { padding: 28px 32px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-1); }
.bounds__h { font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; margin: 0 0 16px; }
.bounds__h--yes { color: var(--ok); }
.bounds__h--no  { color: var(--danger); }
.bounds__list { margin: 0; padding-left: 1.35em; }
.bounds__list li { font-size: 15px; line-height: 1.85; color: var(--ink-2); }
.bounds__list li::marker { color: var(--ok); }
.bounds__list--no li { color: var(--ink-3); }
.bounds__list--no li::marker { color: var(--danger); }

/* ---------- 11 · 价格 ---------- */
.promo {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  padding: 16px 20px; margin-bottom: 28px;
  background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: var(--r-lg);
}
.promo b { color: var(--accent-ink); font-size: 15px; }
.promo span { color: var(--ink-2); font-size: 14px; }
.plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
@media (max-width: 899px) { .plans { grid-template-columns: minmax(0, 1fr); } }
.plan { position: relative; display: flex; flex-direction: column; padding: 28px 26px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); }
.plan.pro { border-color: var(--accent-line); box-shadow: var(--glow); }
.plan__badge {
  align-self: flex-start; margin-bottom: 14px; padding: 4px 10px; border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent); font-size: 11px; font-weight: 700; letter-spacing: .04em;
}
.plan__name { font-family: var(--font-display); font-size: 22px; font-weight: 600; color: var(--ink); }
.plan__was { margin-top: 12px; font-family: var(--font-mono); font-size: 13px; color: var(--ink-3); text-decoration: line-through; }
.plan__now { display: flex; align-items: baseline; gap: 4px; font-family: var(--font-display); font-size: 40px; font-weight: 600; color: var(--ink); line-height: 1.1; }
.plan__now small { font-family: var(--font-body); font-size: 14px; font-weight: 400; color: var(--ink-3); }
.plan__per { margin-top: 6px; font-family: var(--font-mono); font-size: 12px; color: var(--ink-3); }
.plan__list { margin: 18px 0 22px; display: flex; flex-direction: column; gap: 8px; }
.plan__list li { position: relative; padding-left: 18px; font-size: 14px; line-height: 1.6; color: var(--ink-2); }
.plan__list li::before { content: ""; position: absolute; left: 2px; top: .66em; width: 5px; height: 5px; border-radius: 50%; background: var(--accent); }
.plan__cta { margin-top: auto; }

.cmp-scroll { margin-top: 32px; overflow-x: auto; scrollbar-width: thin; }
.cmp { width: 100%; min-width: 640px; border-collapse: collapse; font-size: 14px; }
.cmp caption { text-align: start; padding-bottom: 12px; font-family: var(--font-mono); font-size: 12px; letter-spacing: .06em; color: var(--ink-3); }
.cmp th, .cmp td { padding: 12px 16px; text-align: start; border-bottom: 1px solid var(--line); color: var(--ink-2); }
.cmp thead th { font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; color: var(--ink-3); font-weight: 600; }
.cmp tbody th { color: var(--ink-3); font-weight: 500; }
.cmp b { color: var(--ink); }

/* ---------- 12 · API ---------- */
.api-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: 40px; align-items: start; }
.api-grid > * { min-inline-size: 0; }
@media (max-width: 899px) { .api-grid { grid-template-columns: minmax(0, 1fr); gap: 28px; } }
.api-lead { font-size: 16px; line-height: 1.8; color: var(--ink-2); max-width: 46ch; }
.api-steps { margin: 20px 0 26px; display: flex; flex-direction: column; gap: 12px; counter-reset: step; }
.api-steps li { position: relative; padding-left: 34px; font-size: 14px; line-height: 1.7; color: var(--ink-2); }
.api-steps li::before {
  counter-increment: step; content: counter(step, decimal-leading-zero);
  position: absolute; left: 0; top: 1px; font-family: var(--font-mono); font-size: 12px; font-weight: 600; color: var(--accent-ink);
}
/* ---------- 15 · 能力动画（默认 = 终态；加 .in 后从起点播一次） ---------- */
/* ★ 补全卡（#animComplete）不再做「逐条尾巴入场 stagger」：其内容在每次选风格时由 JS 重建，
   重建会**重新触发** CSS 入场动画（延迟 .20/.32/.44s），导致切换后尾巴 2/3 有一瞬不可见。
   换风格的反馈改由 #genSeed/#genTails 的 ≤150ms 淡入承担（UX 规范 §6.2）。 */

/* ---------- 16 · reduced-motion ---------- */
@media (prefers-reduced-motion: reduce) {
  .wall { transition: none; }
  .gen__caret { animation: none; opacity: 1; }

  /* 模块 01 平铺网格：新增加的过渡在 reduce 下全部置 0 */
  .chipbtn { transition: none; }
  #genSeed, #genTails { transition: none; }

  /* 模块 01：平铺网格的滚动缩小在 reduce 下直接关掉（停在 scale=1 的平铺态） */
  .chips { transform: none !important; }

  /* 悬停：保留阴影/边框变化，去掉位移与缩放 */
  .card { transition: none; }
  .card:hover, .card:focus-visible { --hover-ty: 0px; --hover-s: 1; }

  /* 翻转：改为 200ms 交叉淡入，不做 3D 旋转 */
  .card__inner { transform: none; transition: none; }
  .face { backface-visibility: visible; -webkit-backface-visibility: visible; transition: opacity .2s linear; }
  .face--back { transform: none; opacity: 0; }
  .card.is-flipped .face--front { opacity: 0; }
  .card.is-flipped .face--back { opacity: 1; }
}

/* ============================================================================
   9b · 模块 02 · 演示片舞台（2026-10-13；2026-10-16 去掉四卡羽化段）
   ----------------------------------------------------------------------------
   本块只管 .vstage / .vask 这一套（滚动进视口自动播 → 播完变回片头输入框）。
   ============================================================================ */
/* ---- 演示片舞台 ---- */
.vstage {
  position: relative; margin-top: 40px; aspect-ratio: 16 / 9;
  container-type: inline-size;              /* 供 .vask 用 cqw 精确对齐（见下） */
  border-radius: var(--r-xl); overflow: hidden;
  background: #F4F4F4;                       /* = 原片底色；加载时与视频首帧同色，不闪白 */
  box-shadow: var(--sh-2);
}
.vstage__v {
  position: absolute; inset: 0; width: 100%; height: 100%;
  display: block; object-fit: cover; background: #F4F4F4;
  transition: opacity .55s var(--ease-out);
}
/* 播完淡出，把舞台让给下面那层输入框（两层底色同为 #F4F4F4，看不出接缝） */
.vstage__v.is-out { opacity: 0; }
/* 自动播放不可用（无 JS / 省流 / reduce）时的兜底按钮；有 JS 时由 landing.js 显隐 */
.vstage__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  display: inline-flex; align-items: center; gap: 8px;
  padding: 11px 20px 11px 15px; border-radius: var(--r-pill);
  background: var(--plate); color: var(--plate-ink);
  font-size: 14px; font-weight: 600; letter-spacing: .02em;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .28);
  transition: transform .16s var(--ease-out);
}
.vstage__play svg { width: 17px; height: 17px; fill: currentColor; }
.vstage__play:hover { transform: translate(-50%, -50%) scale(1.04); }

/* ---- 结束态：原片片头那个输入框（真输入框 + 打字机 ghost 层） ---- */
.vask {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding-inline: 24px;
  background: #F4F4F4;
  /* 1em 的标定：盒宽 39em 要**恰好**等于舞台宽的 46.1%（= 原片 886/1920）。
     舞台宽 = min(1280px, 100vw) − 2×.wrap 的 padding（24/40/64 三档），
     用容器查询单位直接量出来，不用猜断点；猜错过一次：按 100vw−48 算，实测 49.3% 而非 46.1%。
     ★ 对齐为什么重要：变形那一刻输入框与视频里的框重合，错 3 个百分点就是肉眼可见的跳。 */
  font-size: clamp(7.5px, 1.04vw, 13.62px); /* 兜底：没有 cqw 的老浏览器（偏差 ≤2pp） */
  opacity: 0; visibility: hidden;
  transition: opacity .55s var(--ease-out), visibility 0s linear .55s;
}
.vask.is-on { opacity: 1; visibility: visible; transition: opacity .55s var(--ease-out), visibility 0s; }
@supports (font-size: 1cqw) {
  .vask { font-size: 1.182cqw; }               /* 精确：舞台宽的 1.182% */
}
/* 手机上按 46.1% 算出来只有 ~158px 宽、正文 6.5px —— 读不了。
   放大到舞台宽的 ~85%，并让变形自带一次「从原片尺寸长上来」的缩放
   （起点 .54 ≈ 158/293），尺寸变化就成了动画而不是跳变。 */
@media (max-width: 767px) {
  .vask { font-size: 7.5px; }
  .vask.is-on .vask__stack { animation: vaskGrow .5s var(--ease-out) both; }
}
@supports (font-size: 1cqw) {
  @media (max-width: 767px) { .vask { font-size: 2.2cqw; } }
}
@keyframes vaskGrow { from { transform: scale(.54); } }

.vask__stack { position: relative; width: min(100%, 39em); }

.vask__row {
  display: flex; align-items: center; gap: .88em;
  width: 100%; height: 5.72em; padding-inline: 1.28em .79em;
  border-radius: 1.5em; background: #FBFBFB;
  box-shadow: 0 1px 2px rgba(23, 24, 27, .05), 0 10px 30px rgba(23, 24, 27, .10);
}
/* 渐变圆：原片是「品红 → 蓝」的圆叠一层中心白色高光
   （网格采样：左 #C13E73 / 右 #3A80C7 / 心 #E8EBFE） */
.vask__mark {
  flex: none; width: 1.58em; height: 1.58em; border-radius: 50%;
  background:
    radial-gradient(circle at 50% 52%, #FFFFFF 0%, rgba(255, 255, 255, .82) 20%, rgba(255, 255, 255, 0) 54%),
    linear-gradient(100deg, #D2417F 0%, #C75BC8 45%, #3E7FE0 100%);
}
.vask__field { position: relative; flex: 1 1 auto; min-width: 0; height: 100%; display: flex; align-items: center; }
.vask__input {
  width: 100%; height: 100%; padding: 0; border: 0; background: none;
  font: inherit; font-size: 1.67em; color: #17181B; outline: none;
}
.vask__input::placeholder { color: #A9ACB3; }
/* 打字机 ghost 层：与 input 同字体、同起点、同垂直居中；caret 由内联流自然跟在文字后面
   （不测宽、不用 canvas measureText ⇒ 不依赖字体度量，任何设备都对齐） */
.vask__ghost {
  position: absolute; inset: 0; display: none; align-items: center;
  pointer-events: none; white-space: pre;
  font-size: 1.67em; color: #17181B;
}
.vask.is-typing .vask__ghost { display: flex; }
.vask.is-typing .vask__input,
.vask.is-typing .vask__input::placeholder { color: transparent; }
.vask__caret {
  flex: none; width: 2px; height: 1.05em; margin-left: .06em;
  background: #3B8CF0; border-radius: 1px;
  animation: vcaret 1.06s steps(1) infinite;
}
@keyframes vcaret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
/* 用户一上手就把显示权交还真输入框（ghost 与假光标让位给原生光标） */
.vask.is-live .vask__ghost { display: none; }
.vask.is-live .vask__input { color: #17181B; }

.vask__send {
  flex: none; width: 2.46em; height: 2.46em; border-radius: 50%;
  display: grid; place-items: center;
  background: #3488DC; color: #FFF;
  transition: background-color .16s var(--ease-out), transform .16s var(--ease-out);
}
.vask__send svg { width: 45%; height: 45%; fill: none; stroke: currentColor; stroke-width: 2.1; stroke-linecap: round; stroke-linejoin: round; }
.vask__send:hover { background: #2A76C6; transform: scale(1.05); }

.vask__meta {
  position: absolute; left: 0; right: 0; top: 100%; margin-top: 2em;
  display: flex; flex-direction: column; align-items: center; gap: .9em;
  text-align: center;
}
.vask__hint { font-size: .92em; letter-spacing: .02em; color: #818389; }
.vask__replay {
  padding: 4px 10px; border-radius: var(--r-pill);
  font-size: .85em; color: #8A8D94;
  transition: color .16s var(--ease-out), background-color .16s var(--ease-out);
}
.vask__replay:hover { color: #17181B; background: rgba(23, 24, 27, .05); }

/* ==========================================================================
   模块 01 · 外围补图层 + 进入羽化（2026-10-17 接入）
   --------------------------------------------------------------------------
   设计稿：`niceidea 风格墙 · 24 风格陈列（换图 + 外围羽化）`
   （Ardot https://ardot.tencent.com/file/737148304365406 的第 02 / 03 帧）

   ★★ 对齐推导 —— 改下面的宽度公式前先把这段看完：
      设 .chips 内容宽 W8（= min(容器宽, 1380px) − 48px 内边距）、列宽 c = (W8 − 7g)/8、
      gap g = 10px、行高 r = c·4/3（格子 aspect-ratio: 3/4）。
      外围层要 12 列、且**列宽必须等于 c** ⇒
        W12 = 12c + 11g = 12(W8 − 7g)/8 + 11g = 1.5·W8 + 0.5g
      代入 g = 10 ⇒ W12 = 1.5·W8 + 5px，就是下面那条 calc。
      两层的几何中心都落在 .sstage__pin 的中心（.chips 靠 place-items:center；
      外围层靠 left/top:50% + translate(-50%,-50%)），且都绕**自身中心**缩放 ⇒
      外层的第 2~4 行 / 第 3~10 列 与中心的 8×3 **逐像素重合**：
        纵向 外层第 2 行上沿到中心 = −(5r+4g)/2 + (r+g) = −(3r+2g)/2 = .chips 上沿到中心 ✓
        横向 外层第 3 列左沿到中心 = −(12c+11g)/2 + (2c+2g) = −(8c+7g)/2 = .chips 左沿 ✓
   ========================================================================== */
.wallring {
  position: absolute; left: 50%; top: 50%; z-index: 0;
  width: calc(1.5 * (min(100%, 1380px) - 48px) + 5px);
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 10px;
  transform: translate(-50%, -50%) scale(var(--s, 1));
  transform-origin: center center;
  will-change: transform, opacity;
  pointer-events: none;             /* 纯装饰：不吃点击、不进 Tab 序 */
  /* 拉远时才浮现：k=0（平铺态）完全透明，且被 .sstage__pin 的 overflow:hidden 裁掉 */
  opacity: var(--k, 0);
  /* 最外缘羽化（与 .sstage__bg 同一套写法）。
     ★ 不透明半径必须**盖过中心 8×3**，否则会把真风格格也压淡：
       中心块半宽 666px / 渐变 rx 1242px = 53.6% ⇒ 取 72% 才安全。 */
  -webkit-mask-image: radial-gradient(62% 58% at 50% 50%, #000 72%, transparent 100%);
  mask-image: radial-gradient(62% 58% at 50% 50%, #000 72%, transparent 100%);
}
.wallring__tile {
  aspect-ratio: 3 / 4; border-radius: 12px; overflow: hidden;
  border: 1px solid var(--line); background: var(--surface-2);
}
.wallring__img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* 窄屏 .chips 换成 6 / 4 列 ⇒ 上面那条列宽等式不成立，外围层直接不显示 */
@media (max-width: 1100px) { .wallring { display: none; } }

/* ---- 进入 · 羽化淡入 ----
   ★ 挂点是 .sstage.rv.in —— 由 site.js 的入场观察器加（reduce 下直接加）
     ⇒ 本特性**零新增 JS**，也不会和已有的 .rv 入场打架。
   ★★ 默认态就是「看得见」：动画只在 .in 存在时才挂 ⇒ JS 不跑也不会把整面墙变透明。 */
/* ★★ 羽化必须**动 mask-position**，不能动 mask-image 的色标：
   实测 Chrome 对 mask-image 的渐变色标**不做插值**（逐帧细采样 0→900ms，
   色标在 283ms 就直接跳到终值）⇒ 视觉上是「啪」一下掀开，不是羽化。
   改成「固定渐变 + mask-size 放大到 210% + 动 mask-position」：
   位移是可平滑插值的属性，且 50%100%（露出渐变下半 ⇒ 底部透明）→ 50%0%（露出上半 ⇒ 全不透明）
   正好是从「底部羽化」到「完全显形」。 */
@keyframes wallFeather {
  from { -webkit-mask-position: 50% 100%; mask-position: 50% 100%; }
  to   { -webkit-mask-position: 50% 0%;   mask-position: 50% 0%; }
}
@keyframes tileIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}
html.js .sstage.rv.in .chips {
  -webkit-mask-image: linear-gradient(180deg, #000 0%, #000 52%, transparent 100%);
  mask-image:         linear-gradient(180deg, #000 0%, #000 52%, transparent 100%);
  -webkit-mask-size: 100% 210%;
  mask-size: 100% 210%;
  animation: wallFeather .9s var(--ease-out) both;
}
html.js .sstage.rv.in .chipbtn {
  animation: tileIn .5s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 24ms);
}

@media (prefers-reduced-motion: reduce) {
  /* reduce：不缩放、不羽化、外围不补图（与设计稿 §04 的降级条款一致） */
  .wallring { display: none; }
  html.js .sstage.rv.in .chips { animation: none; -webkit-mask-image: none; mask-image: none; }
  html.js .sstage.rv.in .chipbtn { animation: none; }
}
