@charset "UTF-8";
/* ==========================================================================
   features.css — 功能页专属像素化模块样式
   只消费 features.html 里已存在的 .fx-* 结构，不触碰 style.css / home.css。
   设计契约：直角（radius 0）、2px 实线边框、平面色块、硬偏移投影、无模糊。
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. 入场方向
   共享观察器只给带 data-reveal 的元素加 .is-revealed，因此位移必须自己写。
   延迟用观察器写入的 --reveal-delay，保留原有的逐项错峰节奏。
   -------------------------------------------------------------------------- */
.fx-from-left[data-reveal],
.fx-from-right[data-reveal] {
  transition: transform var(--anim-slower) var(--ease-out),
              opacity var(--anim-slower) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.fx-from-left[data-reveal] { transform: translateX(-28px); }
.fx-from-left[data-reveal].is-revealed { transform: translateX(0); }

.fx-from-right[data-reveal] { transform: translateX(28px); }
.fx-from-right[data-reveal].is-revealed { transform: translateX(0); }

/* 连续动画总闸门：features.html 已把 .fx-arch-stack 包进 <div class="fx-gate">；
   .is-live 由 features-fx.js 的闸门观察器按进出视口自动增删，不需要手写；
   display:contents 让闸门不参与布局，.fx-arch-layout 的两栏网格因此不受影响。 */
.fx-gate { display: contents; }
.fx-gate:not(.is-live) .fx-arch-packet { animation-play-state: paused; }
.fx-gate.is-live .fx-arch-packet { animation-play-state: running; }

/* --------------------------------------------------------------------------
   1. #overview — 作品集式外框 + 四角像素括号
   -------------------------------------------------------------------------- */
.fx-replica-frame {
  position: relative;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  background: var(--surface-solid);
  padding: 10px;
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.45);
}

.fx-replica-corner {
  position: absolute;
  width: 18px;
  height: 18px;
  pointer-events: none;
  z-index: 2;
}

.fx-replica-corner.is-tl {
  top: -2px;
  left: -2px;
  border-top: 2px solid var(--green);
  border-left: 2px solid var(--green);
}
.fx-replica-corner.is-tr {
  top: -2px;
  right: -2px;
  border-top: 2px solid var(--green);
  border-right: 2px solid var(--green);
}
.fx-replica-corner.is-bl {
  bottom: -2px;
  left: -2px;
  border-bottom: 2px solid var(--green);
  border-left: 2px solid var(--green);
}
.fx-replica-corner.is-br {
  bottom: -2px;
  right: -2px;
  border-bottom: 2px solid var(--green);
  border-right: 2px solid var(--green);
}

/* 内部 UI 自带 zoom，这里只负责裁切，不碰 .ui-* 的任何规则 */
.fx-replica-frame .replica-scroll {
  position: relative;
  overflow: hidden;
  border-radius: 0;
}

/* --------------------------------------------------------------------------
   2. #pain — 前后对照双终端
   3 列 1fr auto 1fr，中间一列只放 2px 分隔线；窄屏折成单列并隐藏分隔线。
   -------------------------------------------------------------------------- */
.fx-pain-grid {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: 18px;
  align-items: stretch;
  margin-top: 30px;
}

.fx-pain-col {
  position: relative;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  background: var(--surface-solid);
  transition: border-color var(--anim-base) var(--ease-out),
              transform var(--anim-base) var(--ease-out);
}

/* 前：整体压暗、只留一个偏红的告警色，视觉上就是“更糟的那一边” */
.fx-pain-col.is-before {
  background: var(--surface-solid);
  border-color: var(--line);
  opacity: 0.92;
}
.fx-pain-col.is-before .fx-pain-head { color: var(--muted); }
.fx-pain-col.is-before .fx-pain-head .dot {
  background: #a35d5d;
  border-color: #a35d5d;
}
.fx-pain-col.is-before .fx-pain-item { border-left-color: #6d4343; }
.fx-pain-col.is-before .fx-pain-glyph {
  border-color: #6d4343;
  color: #a35d5d;
}
.fx-pain-col.is-before h3 { color: var(--ink-soft); }

/* 后：绿色作为“已解决”的单一强调色 */
.fx-pain-col.is-after {
  border-color: var(--green);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.45);
}
.fx-pain-col.is-after .fx-pain-head { color: var(--green); }
.fx-pain-col.is-after .fx-pain-head .dot {
  background: var(--green);
  border-color: var(--green);
}
.fx-pain-col.is-after .fx-pain-glyph {
  border-color: var(--green);
  color: var(--green);
}

.fx-pain-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 13px 14px;
  border-bottom: 2px solid var(--line);
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11.5px;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.fx-pain-head .dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border: 2px solid currentColor;
  border-radius: 0;
  background: currentColor;
}

.fx-pain-list {
  display: grid;
  gap: 0;
  padding: 10px;
}

.fx-pain-item {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 11px 12px;
  border-left: 2px solid var(--line-strong);
  border-radius: 0;
  transition: border-color var(--anim-base) var(--ease-out),
              background var(--anim-base) var(--ease-out);
}

.fx-pain-item + .fx-pain-item { margin-top: 4px; }

.fx-pain-item h3 {
  margin: 0 0 4px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0;
  color: var(--ink);
}

.fx-pain-item p {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--muted);
}

/* 已解决项：左侧线换成绿色，并把正文提亮一档 */
.fx-pain-item.is-solved { border-left-color: var(--green); }
.fx-pain-item.is-solved h3 { color: var(--green); }
.fx-pain-item.is-solved p { color: var(--ink-soft); }

.fx-pain-glyph {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  background: transparent;
  color: var(--muted);
}
.fx-pain-glyph svg { display: block; width: 12px; height: 12px; }

/* 分隔线本身没有 data-reveal，父级也不是 data-reveal-group，
   所以无法借共享观察器触发；用自身的一次性入场动画最稳。 */
.fx-pain-divider {
  width: 2px;
  align-self: stretch;
  background: var(--line-strong);
  transform: scaleY(0);
  transform-origin: top;
  animation: fx-divider-in 700ms var(--ease-out) both;
}

@keyframes fx-divider-in {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}

/* --------------------------------------------------------------------------
   3. #features — 8 宫格，2px 缝隙透出底色形成像素网
   -------------------------------------------------------------------------- */
.fx-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 2px;
  background: var(--line);
  border: 2px solid var(--line);
  margin-top: 30px;
}

.fx-card {
  position: relative;
  overflow: hidden;
  border: 2px solid transparent;
  border-radius: 0;
  background: var(--surface-solid);
  padding: 22px 20px 24px;
  transition: border-color var(--anim-base) var(--ease-out),
              transform var(--anim-base) var(--ease-out),
              box-shadow var(--anim-base) var(--ease-out);
}

.fx-card:hover,
.fx-card:focus-within {
  border-color: var(--green);
  transform: translateY(-2px);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.45);
}

.fx-card h3 {
  margin: 0 0 8px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.fx-card p {
  margin: 0;
  font-size: 12.8px;
  line-height: 1.75;
  color: var(--muted);
  font-family: Inter, system-ui, -apple-system, 'Segoe UI', sans-serif;
}

.fx-card-idx {
  position: absolute;
  top: 10px;
  right: 12px;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 26px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--subtle);
  opacity: 0.55;
  pointer-events: none;
  user-select: none;
}

.fx-card-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  margin-bottom: 14px;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  color: var(--green);
  transition: border-color var(--anim-base) var(--ease-out),
              background var(--anim-base) var(--ease-out);
}
.fx-card-icon svg { display: block; width: 16px; height: 16px; }

.fx-card:hover .fx-card-icon {
  border-color: var(--green);
  background: var(--surface-hover);
}

/* 扫光条：2px 高、横向渐变。用固定的 240px 位移而不是百分比，
   因为 translateY 的百分比以元素自身高度（2px）为基准，扫不动卡片。 */
.fx-card-scan {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg,
      transparent 0%,
      rgba(82, 177, 123, 0.15) 18%,
      var(--green) 50%,
      rgba(82, 177, 123, 0.15) 82%,
      transparent 100%);
  opacity: 0;
  transform: translateY(-2px);
  pointer-events: none;
}

.fx-card:hover .fx-card-scan,
.fx-card:focus-within .fx-card-scan {
  animation: fx-scan 900ms var(--ease-out) both;
}

@keyframes fx-scan {
  0%   { transform: translateY(-2px); opacity: 0; }
  8%   { opacity: 0.9; }
  85%  { opacity: 0.5; }
  100% { transform: translateY(240px); opacity: 0; }
}

/* 标题 RGB 错位：只在 .is-on 时触发一次，steps 让它像信号故障而不是渐变 */
.section-head[data-fx-once].is-on h2 {
  animation: fx-glitch 600ms steps(1, end) 1 both;
}

@keyframes fx-glitch {
  0%   { text-shadow: 2px 0 var(--green), -2px 0 var(--blue); transform: translateX(0); }
  15%  { text-shadow: -3px 0 var(--green), 3px 0 var(--blue); transform: translateX(1px); }
  30%  { text-shadow: 3px 0 var(--blue), -3px 0 var(--green); transform: translateX(-1px); }
  45%  { text-shadow: 1px 0 var(--green), -1px 0 var(--blue); transform: translateX(0); }
  60%  { text-shadow: -2px 0 var(--blue), 2px 0 var(--green); transform: translateX(1px); }
  100% { text-shadow: none; transform: translateX(0); }
}

/* --------------------------------------------------------------------------
   4. #architecture — 左栈 + 右信任列
   -------------------------------------------------------------------------- */
.fx-arch-layout {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 24px;
  align-items: start;
  margin-top: 30px;
}

/* --fx-arch-h 是数据包下落的最大位移，纯 CSS 拿不到栈的真实高度，
   所以给一个 420px 的经验值；若以后某层更高，只需在这个变量上覆盖。 */
.fx-arch-stack {
  position: relative;
  --fx-arch-h: 420px;
}

.fx-arch-layer {
  position: relative;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  background: var(--surface-solid);
  padding: 16px 18px;
  transition: border-color var(--anim-base) var(--ease-out),
              background var(--anim-base) var(--ease-out);
}

.fx-arch-layer h3 {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--ink);
}

.fx-arch-layer p {
  margin: 8px 0 0;
  font-size: 12.6px;
  line-height: 1.75;
  color: var(--muted);
}

.fx-arch-layer.is-engine {
  border-color: var(--green);
  background: var(--green-soft);
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.45);
}
.fx-arch-layer.is-engine h3 { color: var(--green); }
.fx-arch-layer.is-engine p { color: var(--ink-soft); }

.fx-arch-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  flex-wrap: wrap;
}

.fx-arch-tag {
  flex: 0 0 auto;
  border: 1px solid var(--line-strong);
  border-radius: 0;
  padding: 3px 7px;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 10px;
  line-height: 1.4;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

.fx-arch-arrow {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 9px 0;
  color: var(--line-strong);
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 10px;
  line-height: 1.3;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
}
.fx-arch-arrow svg { display: block; opacity: 0.9; }
.fx-arch-arrow span { color: var(--subtle); }

/* 纵向数据包：默认 paused + opacity:0，只有祖先 .fx-gate 带上 .is-live
   （架构区块进入视口时由闸门观察器添加）才真正开跑；
   若 JS 从未执行，它就一直是不可见的，不会在半空中冻成一个静止的点。 */
.fx-arch-packet {
  position: absolute;
  top: 0;
  left: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 0;
  background: var(--green);
  opacity: 0;
  pointer-events: none;
  animation: fx-packet-down 3.4s linear infinite both;
  animation-play-state: paused;
}

@keyframes fx-packet-down {
  0%   { transform: translateY(0); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: translateY(var(--fx-arch-h, 420px)); opacity: 0; }
}

.fx-trust-list {
  display: grid;
  gap: 2px;
  background: var(--line);
  border: 2px solid var(--line);
}

.fx-trust-item {
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  padding: 15px 16px;
  border: 2px solid transparent;
  border-radius: 0;
  background: var(--surface-solid);
  transition: border-color var(--anim-base) var(--ease-out);
}

.fx-trust-item:hover { border-color: var(--green); }

.fx-trust-item h3 {
  margin: 0 0 5px;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.fx-trust-item p {
  margin: 0;
  font-size: 12.4px;
  line-height: 1.72;
  color: var(--muted);
}

.fx-trust-icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  color: var(--green);
}
.fx-trust-icon svg { display: block; }

/* --------------------------------------------------------------------------
   5. #start — 三步 + 终端代码卡
   -------------------------------------------------------------------------- */
.fx-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px;
  background: var(--line);
  border: 2px solid var(--line);
  margin-top: 30px;
}

.fx-step {
  position: relative;
  border: 2px solid transparent;
  border-radius: 0;
  background: var(--surface-solid);
  padding: 22px 20px 24px;
  transition: border-color var(--anim-base) var(--ease-out);
}

.fx-step:hover { border-color: var(--line-strong); }

.fx-step h3 {
  margin: 16px 0 8px;
  font-size: 14.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--ink);
}

.fx-step p {
  margin: 0;
  font-size: 12.6px;
  line-height: 1.75;
  color: var(--muted);
}

/* 圆环外框 44×44，数字用 DM Mono 垂直居中 */
.fx-step-num {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 0;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 15px;
  line-height: 1;
  letter-spacing: 0.02em;
  color: var(--green);
  background: var(--surface-solid);
}

.fx-step-ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform: rotate(-90deg);
}

.fx-ring-track {
  fill: none;
  stroke: var(--line-strong);
  stroke-width: 2;
  stroke-linecap: butt;
}

/* r=21 的周长是 2π×21 ≈ 131.95，取 132 让描边刚好闭合，不留缝也不重叠 */
.fx-ring-fill {
  fill: none;
  stroke: var(--green);
  stroke-width: 2;
  stroke-linecap: butt;
  stroke-dasharray: 132;
  stroke-dashoffset: 132;
  transition: stroke-dashoffset 900ms var(--ease-out);
}

[data-fx-ring].is-drawn .fx-ring-fill { stroke-dashoffset: 0; }

.fx-code-card {
  position: relative;
  overflow: hidden;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  background: var(--surface-solid);
  margin-top: 24px;
  box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.45);
}

/* 扫描线只作为氛围层，必须不拦截点击，也不参与任何布局 */
.fx-code-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(255, 255, 255, 0.028) 0px,
    rgba(255, 255, 255, 0.028) 1px,
    transparent 1px,
    transparent 4px
  );
}

.fx-code-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-bottom: 2px solid var(--line);
  background: var(--surface-soft);
}

.fx-code-dots {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
}
.fx-code-dots i {
  display: block;
  width: 8px;
  height: 8px;
  border-radius: 0;
  background: var(--line-strong);
}
.fx-code-dots i:first-child { background: var(--green); }

.fx-code-title {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 10.5px;
  line-height: 1.5;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.fx-code-title svg { flex: 0 0 auto; opacity: 0.8; }

.fx-code-card .copy-button {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  padding: 5px 10px;
  background: transparent;
  color: var(--muted);
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 10px;
  line-height: 1.4;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--anim-fast) var(--ease-out),
              color var(--anim-fast) var(--ease-out),
              background var(--anim-fast) var(--ease-out);
}
.fx-code-card .copy-button:hover {
  border-color: var(--green);
  color: var(--green);
  background: var(--surface-hover);
}

/* JS 复制成功后加 .is-copied，给一个明确的成功态（边框 + 文字同时变绿） */
.fx-code-card .copy-button.is-copied {
  border-color: var(--green);
  color: var(--green);
  background: var(--green-soft);
}

.fx-code-card .code-body {
  position: relative;
  z-index: 1;
  margin: 0;
  padding: 16px 18px;
  overflow-x: auto;
  background: transparent;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12.2px;
  line-height: 1.85;
  tab-size: 2;
  color: var(--ink-soft);
}

.fx-code-card code#curl-snippet {
  display: block;
  background: none;
  padding: 0;
  border: 0;
  color: inherit;
  font: inherit;
  white-space: pre;
}

.endpoint-hint {
  margin: 12px 0 0;
  padding-left: 10px;
  border-left: 2px solid var(--line-strong);
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11px;
  line-height: 1.7;
  letter-spacing: 0.02em;
  color: var(--subtle);
}

/* 一次性擦除入场：写成 .is-on 触发的 animation 而不是常驻 clip-path，
   这样 JS 不跑时卡片仍然完整可见（宁可没有动画，也不要空白）。 */
.fx-code-card[data-fx-once].is-on {
  animation: fx-code-wipe 700ms var(--ease-out) both;
}

@keyframes fx-code-wipe {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* --------------------------------------------------------------------------
   6. #faq — 原生 details 的像素手风琴
   -------------------------------------------------------------------------- */
.fx-faq-list {
  margin-top: 30px;
}

.fx-faq-item {
  border: 2px solid var(--line);
  border-radius: 0;
  background: var(--surface-solid);
  margin-bottom: 2px;
  overflow: hidden;
  transition: border-color var(--anim-base) var(--ease-out),
              background var(--anim-base) var(--ease-out);
}

.fx-faq-item[open] {
  border-color: var(--line-strong);
  border-left-color: var(--green);
  background: var(--surface-soft);
}

.fx-faq-item summary {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 16px;
  border-left: 2px solid transparent;
  border-radius: 0;
  cursor: pointer;
  list-style: none;
  font-family: 'DM Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 12.8px;
  line-height: 1.6;
  letter-spacing: 0.01em;
  color: var(--ink);
  transition: color var(--anim-fast) var(--ease-out),
              background var(--anim-fast) var(--ease-out);
}

.fx-faq-item summary::-webkit-details-marker { display: none; }
.fx-faq-item summary::marker { content: ""; }

.fx-faq-item summary:hover { color: var(--green); }
.fx-faq-item[open] summary { color: var(--green); }

/* 加号：两根 2px 实心条，展开时只收掉竖条 → 变成减号 */
.fx-faq-marker {
  position: relative;
  flex: 0 0 auto;
  width: 14px;
  height: 14px;
  border: 2px solid var(--line-strong);
  border-radius: 0;
  transition: border-color var(--anim-fast) var(--ease-out);
}

.fx-faq-marker::before,
.fx-faq-marker::after {
  content: "";
  position: absolute;
  background: currentColor;
  transition: transform var(--anim-fast) var(--ease-out),
              opacity var(--anim-fast) var(--ease-out);
}

.fx-faq-marker::before {
  top: 50%;
  left: 3px;
  right: 3px;
  height: 2px;
  margin-top: -1px;
}

.fx-faq-marker::after {
  left: 50%;
  top: 3px;
  bottom: 3px;
  width: 2px;
  margin-left: -1px;
}

.fx-faq-item[open] .fx-faq-marker {
  border-color: var(--green);
  color: var(--green);
}
.fx-faq-item[open] .fx-faq-marker::after {
  transform: scaleY(0);
  opacity: 0;
}

/* 不碰 details 的显隐机制，只给答案排内距 */
.fx-faq-item > p {
  margin: 0;
  padding: 0 18px 17px 42px;
  font-size: 12.8px;
  line-height: 1.8;
  color: var(--ink-soft);
}

/* --------------------------------------------------------------------------
   7. .fx-aura — 页面底噪
   固定在最底层，pointer-events:none，绝不遮挡内容或拦截交互。
   -------------------------------------------------------------------------- */
.fx-aura {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background-image:
    radial-gradient(60% 45% at 18% 8%, rgba(82, 177, 123, 0.05) 0%, rgba(82, 177, 123, 0) 70%),
    radial-gradient(55% 40% at 88% 12%, rgba(134, 160, 206, 0.04) 0%, rgba(134, 160, 206, 0) 72%),
    radial-gradient(70% 50% at 50% 100%, rgba(82, 177, 123, 0.035) 0%, rgba(82, 177, 123, 0) 75%),
    repeating-linear-gradient(
      to bottom,
      rgba(255, 255, 255, 0.012) 0px,
      rgba(255, 255, 255, 0.012) 1px,
      transparent 1px,
      transparent 3px
    );
  background-repeat: no-repeat;
  background-size: cover;
}

/* --------------------------------------------------------------------------
   8. 响应式
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .fx-pain-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
  }
  .fx-pain-divider {
    display: none;
  }
  .fx-card-grid {
    grid-template-columns: minmax(0, 1fr);
  }
  .fx-arch-layout {
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
  }
  .fx-steps {
    grid-template-columns: minmax(0, 1fr);
  }
  .fx-arch-tag { white-space: normal; }
  .fx-card-idx { font-size: 22px; }
  .fx-faq-item > p { padding-left: 18px; }
}

/* --------------------------------------------------------------------------
   9. 降低动态效果：全部动画/过渡关掉，但状态必须落到终态，
      否则会出现“圆环只画了一半”“内容停在位移外”这类更糟的结果。
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .fx-from-left[data-reveal],
  .fx-from-right[data-reveal] {
    transform: none !important;
    opacity: 1 !important;
    transition: none !important;
  }

  .fx-card,
  .fx-step,
  .fx-arch-layer,
  .fx-trust-item,
  .fx-pain-col,
  .fx-pain-item,
  .fx-faq-item,
  .fx-faq-item summary,
  .fx-faq-marker,
  .fx-faq-marker::before,
  .fx-faq-marker::after,
  .fx-code-card .copy-button,
  .fx-arch-tag {
    transition: none !important;
  }

  .fx-card,
  .fx-card-scan,
  .fx-code-card[data-fx-once],
  .fx-code-card[data-fx-once].is-on,
  .section-head[data-fx-once].is-on h2,
  .fx-arch-packet {
    animation: none !important;
  }

  .fx-card:hover,
  .fx-card:focus-within {
    transform: none !important;
    box-shadow: none !important;
  }

  .section-head[data-fx-once].is-on h2 { text-shadow: none !important; }

  .fx-pain-divider {
    animation: none !important;
    transform: scaleY(1) !important;
  }

  .fx-ring-fill {
    transition: none !important;
    stroke-dashoffset: 0 !important;
  }

  .fx-arch-packet {
    opacity: 0 !important;
    transform: none !important;
  }

  .fx-card-scan { display: none !important; }

  .fx-code-card[data-fx-once] { clip-path: none !important; }
}

/* --------------------------------------------------------------------------
   10. 打印：去掉底噪与扫描层，保留 2px 边框保证结构仍可读
   -------------------------------------------------------------------------- */
@media print {
  .fx-aura,
  .fx-card-scan,
  .fx-code-card::after {
    display: none !important;
  }

  .fx-replica-frame,
  .fx-card,
  .fx-pain-col,
  .fx-arch-layer,
  .fx-trust-item,
  .fx-step,
  .fx-faq-item,
  .fx-code-card,
  .section-head[data-fx-once].is-on h2,
  .fx-arch-packet,
  .fx-pain-divider,
  .fx-ring-fill {
    animation: none !important;
    transition: none !important;
    transform: none !important;
  }

  .fx-pain-divider { transform: scaleY(1) !important; }
  .fx-ring-fill { stroke-dashoffset: 0 !important; }
  .fx-code-card[data-fx-once] { clip-path: none !important; }
  .fx-card { box-shadow: none !important; }
  .fx-pain-col.is-before { opacity: 1 !important; }
  .fx-card[data-reveal],
  .fx-from-left[data-reveal],
  .fx-from-right[data-reveal] { opacity: 1 !important; }
}

/* --------------------------------------------------------------------------
   11. #overview — 侧栏飞出菜单的行距与配比（只覆盖比例，不覆盖定位）

   问题不在「好不好看」，而在层级读错了。真实桌面端的飞出菜单是「图标 + 标签」
   的行式菜单：每行左侧一个跟侧栏同笔画的图标，右侧跟文字，行与行之间留足呼吸，
   所以眼睛先把它读成一列可点的条目。复刻版里这些行是纯文字、5px 上下内边距、
   12px 字号，整块读起来像一段被折行的说明文；132px 的最小宽度也放不下图标，
   于是「组名 → 条目」的层级被压平成同一档文字。

   因此这里只做两件事：给行加上 flex 基线对齐，让图标与标签各占一个子项；
   把行高抬到接近系统菜单的 32–36px 档位，并加宽弹出的最小宽度给图标让位。
   定位（top/left）、开合过渡、visibility/opacity/transform 状态一概不动——
   那部分是正确的，hover 出层的节奏必须原样保留。

   作用域全部挂在 .fx-replica-frame 下：features.css 只被 features.html 引用，
   且加载在 style.css 之后，因此不污染全站，也不需要改 style.css 一行。
   -------------------------------------------------------------------------- */
.fx-replica-frame .ui-nav-popover {
  min-width: 176px;      /* 132px 装不下「图标 + 标签」，加宽给 15px 图标让位 */
  gap: 2px;              /* 行间缝隙保持 2px，靠单行内边距撑开高度，而非拉开间隙 */
  padding: 8px;
}

.fx-replica-frame .ui-popover-label {
  padding: 6px 10px 8px; /* 上多下少：让组名离上边框远一点，离首个条目近一点 */
  letter-spacing: .06em; /* 小字号大写需要更多字距才不糊成一团 */
}

.fx-replica-frame .ui-popover-item {
  display: flex;         /* 图标与标签共处一条基线，而不是各自成行 */
  align-items: center;
  gap: 9px;              /* 图标与文字之间的呼吸，接近桌面端原生菜单的 9–10px */
  padding: 9px 10px;
  font-size: 12.5px;
  line-height: 1.25;     /* 行高交给 padding 决定高度，避免双重留白显得松散 */
}

.fx-replica-frame .ui-popover-item > svg {
  flex: 0 0 auto;        /* 禁止被「API Key」这类长标签挤压而变形 */
  opacity: .85;          /* 图标比文字略退一档，保持标签为第一阅读目标 */
}

.fx-replica-frame .ui-popover-item.is-active > svg,
.fx-replica-frame .ui-popover-item:hover > svg { opacity: 1; }
