/* ============================================================
   helix.css — HELIX 皮肤 · 首页整套重排
   ------------------------------------------------------------
   作用域：html[data-skin="helix"]（入口 index.html 的 <html> 带此属性；
   去掉它即回落到旧皮肤，便于对照）

   设计 DNA（取自参考站 HELIX / Motion System）：
   · 冷蓝黑底 + 单点薄荷强调，全站只有一处彩色
   · 零圆角感、零投影、零 blur 光斑；分层只靠 1px 发丝线
   · 巨字排版：字重 800、行高 .92、字距收紧，一半实心一半描边
   · 等宽大写微标签做元信息（编号 / 计数 / 状态）
   · 88px 栅格底纹 + 顶部径向微光（只是底色，不是元素 glow）

   布局重排（不复用旧首页的侧栏 + 卡片宫格）：
   固定横向导航 → 巨字 Hero（左下正文 / 右下四宫格数据）
   → 跑马灯条 → 分类分段 + 全幅索引行 → 巨字 OUTRO 收尾
   索引行 hover 整行反色（薄荷底 + 深色字），是这套皮肤的主交互语言。
   ============================================================ */

html[data-skin="helix"] {
  /* --- 正文字号缩放系数（设置里那条滑杆驱动，1 = 100%）---
     只乘到 font-size / line-height 上（见各文件的 calc(... * var(--hx-fsk, 1))），
     卡片宽度、间距、栅格一律不动 —— 字号变大是「字更大」，不是「整页放大」。
     旧实现用 html{zoom}，会让有效视口变窄、整站塌成窄屏并重排，已废弃。 */
  --hx-fsk: 1;
  /* --- 两套主题共用的结构令牌 --- */
  --hx-pad: clamp(18px, 4.6vw, 84px);
  /* --- 动效令牌（三条曲线各司其职，别混用）---
     glide  快起柔停、不过冲：默认曲线。颜色/透明度/底色过渡等"不该弹"的属性。
     spring 过冲回落：弹窗/面板/气泡落位、松手回弹。Kinetics 的核心曲线，
             "Motion that has weight"——落位带一下重量感，而不是机械到位。
     slide  越线即回：toast/下拉从边缘滑入，过目标位一点点再收回。
     时长节奏：按压 ≤0.08s（触觉）/ 微交互 0.2-0.3s / 落位 0.34s /
     退场一律快于入场（0.12-0.15s），离开不要拖泥带水。 */
  --hx-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --hx-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --hx-slide: cubic-bezier(0.18, 1.25, 0.4, 1);
  /* 字体令牌统一在 main.css :root（--hx-sans / --hx-mono），这里不再重复定义 */
  --hx-nav-h: 70px;

  /* 反色行（hover / focus）两套主题一致：薄荷底 + 近黑字 —— 这是皮肤的主交互语言 */
  --hx-inv-bg: #5ef2d6;
  --hx-inv-ink: #06080d;
  --hx-inv-dim: rgba(6, 8, 13, 0.7);

  /* --- 弹窗层统一令牌（全站唯一来源）---
     以前每处弹窗各写各的 rgba/blur/圆角，于是同一站里长出四套：
     遮罩 .62/.42/.34 三种深浅、blur 3/2/0 三档、圆角 0/3/6 三种。
     现在所有弹层（首页大弹窗、工具排序、我的时间、图标工坊、五子棋、
     功能预览、登录浮层）只引用下面这套，改一处即全站生效。
     ⚠️ 新加弹层也请用令牌，不要再写字面量 rgba。 */
  --hx-mask-blur: 3px;              /* 遮罩毛玻璃：全站同一档 */
  --hx-dlg-radius: 0;               /* 零圆角 —— 皮肤 DNA「零圆角感」，圆角只留给按钮/输入框 */
  --hx-dlg-line: var(--hx-line-2);  /* 面板边框：一圈 1px 发丝线，永不加深 */
  --hx-dlg-bg: var(--hx-bg);        /* 面板底 = 页面底色，层次靠遮罩压暗，不靠亮色上浮 */
  --hx-dlg-shadow: none;            /* 零投影（换皮方向B：--shadow-* 已全部置透明） */

  /* z 轴按语义分档，不按"谁后加"排。
     旧代码里出现过「我的时间 300 高于登录 240、却低于图标工坊 400」的乱序。 */
  --hx-z-viewer: 90;    /* 页内功能预览：页面附属层，最低 */
  --hx-z-dlg: 200;      /* 页面级弹窗：全部功能 / 工具排序 / 五子棋 */
  --hx-z-pop: 240;      /* 轻浮层：登录 / 账户菜单（无遮罩，挂在按钮下方） */
  --hx-z-sheet: 300;    /* 全屏详情页：我的时间 */
  --hx-z-tool: 400;     /* 工具页内弹窗：图标工坊 */
  --hx-z-anchor: 1100;  /* 锚定浮层：日期/时间选择、取色器 —— 必须高于所有面板，
                           否则"从详情页里点出来的浮层"会被详情页自己盖住 */
  --hx-z-tip: 1200;     /* 气泡提示：永远在最上 */
}

/* ---------- 深色（默认，对齐参考站） ---------- */
html[data-skin="helix"][data-theme="dark"] {
  --hx-bg: #08090e;
  --hx-ink: #e9edf6;
  --hx-dim: #9aa3b8;      /* 对 #08090e 约 8.3:1 */
  --hx-dim2: #7c869b;     /* 对 #08090e 约 5.4:1 */
  --hx-line: rgba(255, 255, 255, 0.085);
  --hx-line-2: rgba(255, 255, 255, 0.16);
  --hx-field-bg: rgba(255, 255, 255, 0.035);
  --hx-grid: rgba(255, 255, 255, 0.075);
  --hx-acc: #5ef2d6;
  --hx-nav-bg: rgba(8, 9, 14, 0.9);
  --hx-strip-bg: rgba(255, 255, 255, 0.014);
  --hx-track: rgba(255, 255, 255, 0.06);
  --hx-glow-a: rgba(94, 242, 214, 0.055);
  --hx-glow-b: rgba(96, 140, 255, 0.045);
  --hx-mask: rgba(6, 8, 13, 0.62);   /* 弹窗遮罩：全站统一，深浅主题只换这一个值 */

  /* 零投影（换皮方向B）：旧皮肤的 --shadow-1/2 在全站有 40+ 处使用点
     （面板/卡片/文件信息/弹层/工具提示），在这里置成透明空值一处收尽。
     ⚠️ 不能写成 none：gomoku.css:722 是双层写法
     `box-shadow: var(--shadow-1), inset 0 0 0 2px var(--surface)`，
     none 混进多层列表会让整条声明失效，连带弄丢那个 inset 环。 */
  --shadow-1: 0 0 0 rgba(0, 0, 0, 0);
  --shadow-2: 0 0 0 rgba(0, 0, 0, 0);

  /* 站内工具视图的 token 一起收编成冷色，进出工具页不跳色 */
  --bg: #0b0c12;
  --surface: #111319;
  --border: #23262f;
  --border-strong: #31353f;
  --text: #e9edf6;
  --text-2: #a8b0c4;
  --text-3: #8a92a8;
  --icon-bg: #1a1d25;
  --icon-fg: #cfd6e4;
  --accent: #5ef2d6;
  --accent-text: #8ff7e3;
  --accent-soft-bg: rgba(94, 242, 214, 0.1);
  --accent-soft-border: rgba(94, 242, 214, 0.3);
  --r-card: 6px;
  --r-btn: 4px;

  /* 深色主题必须声明 color-scheme，否则原生控件（date/time 日历面板、
     select 下拉、滚动条、自动填充底色）一律按浅色系统 UI 渲染 ——
     深色页面上点日期会弹出一整块白底系统日历。浅色块早已声明，这里原先是漏的。 */
  color-scheme: dark;
}

/* ---------- 浅色 ----------
   薄荷在白底上几乎看不见，所以浅色把「强调」拆成两档：
   · 文字/描边/进度条 → 墨绿 #0a6b58（对 #f2f3f6 约 5.7:1，够 WCAG）
   · 只有整行反色时薄荷才出场（填充不算文字对比度），一按就亮，是这套皮的记忆点 */
html[data-skin="helix"][data-theme="light"] {
  --hx-bg: #f2f3f6;
  --hx-ink: #0a0c12;
  --hx-dim: #555d6e;      /* 对 #f2f3f6 约 6.0:1 */
  --hx-dim2: #5b6475;     /* 约 5.3:1 */
  --hx-line: rgba(10, 12, 18, 0.13);
  --hx-line-2: rgba(10, 12, 18, 0.22);
  --hx-field-bg: rgba(10, 12, 18, 0.03);
  --hx-grid: rgba(10, 12, 18, 0.055);
  --hx-acc: #0a6b58;
  --hx-nav-bg: rgba(242, 243, 246, 0.92);
  --hx-strip-bg: rgba(10, 12, 18, 0.02);
  --hx-track: rgba(10, 12, 18, 0.06);
  --hx-glow-a: rgba(10, 140, 120, 0.06);
  --hx-glow-b: rgba(96, 140, 255, 0.04);
  --hx-mask: rgba(242, 243, 246, 0.66);   /* 弹窗遮罩：浅色主题用近白，与深色同一套令牌 */

  /* 零投影：同深色块（原因见上，不能写 none） */
  --shadow-1: 0 0 0 rgba(0, 0, 0, 0);
  --shadow-2: 0 0 0 rgba(0, 0, 0, 0);

  --bg: #f2f3f6;
  --surface: #ffffff;
  --border: #e2e4e9;
  --border-strong: #cbd0d9;
  --text: #0a0c12;
  --text-2: #4b5364;
  --text-3: #5b6475;
  --icon-bg: #eceef2;
  --icon-fg: #2c3240;
  --accent: #0a6b58;
  --accent-text: #065043;
  --accent-soft-bg: rgba(10, 107, 88, 0.08);
  --accent-soft-border: rgba(10, 107, 88, 0.28);
  --r-card: 6px;
  --r-btn: 4px;
  color-scheme: light;
}

html[data-skin="helix"] body {
  background: var(--hx-bg);
  color: var(--hx-ink);
}

/* 旧首页外壳（.app）默认收起：display:flex 会压过 [hidden]，必须 !important */
html[data-skin="helix"] #legacy-app[hidden] { display: none !important; }
html[data-skin="helix"] .hx[hidden] { display: none !important; }

/* ============================================================
   1. 首页外壳 + 背景层
   ============================================================ */
.hx {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  overflow-x: clip;
}

/* 顶部径向微光：极低透明度，只做空气感，不产生「光斑」观感 */
.hx::before {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(62% 46% at 84% 0%, var(--hx-glow-a), transparent 66%),
    radial-gradient(46% 38% at 2% 94%, var(--hx-glow-b), transparent 70%);
}

/* 88px 栅格底纹：向顶部聚拢，往下淡出（同参考站 mask 手法） */
.hx::after {
  content: "";
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--hx-grid) 1px, transparent 1px),
    linear-gradient(to bottom, var(--hx-grid) 1px, transparent 1px);
  background-size: 88px 88px;
  opacity: 0.6;
  -webkit-mask-image: radial-gradient(128% 92% at 50% 0%, #000 12%, transparent 76%);
          mask-image: radial-gradient(128% 92% at 50% 0%, #000 12%, transparent 76%);
}

/* 滚动进度条 */
.hx-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 80;
  background: var(--hx-track);
  pointer-events: none;
}
.hx-progress i {
  display: block; height: 100%; width: 100%;
  background: var(--hx-acc);
  transform: scaleX(0); transform-origin: left;
}

/* ============================================================
   2. 固定横向导航
   ============================================================ */
.hx-nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 70;
  display: flex; align-items: center;
  gap: clamp(12px, 1.8vw, 28px);
  height: var(--hx-nav-h);
  padding: 0 var(--hx-pad);
  border-bottom: 1px solid var(--hx-line-2);
  background: var(--hx-nav-bg);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  /* 主题切换时导航整体渐变过渡，不硬跳 */
  transition: background-color 0.35s var(--hx-ease), border-color 0.35s var(--hx-ease);
}
/* 导航下方 18px 渐隐：内容滚到导航底下时不会和分界线糊在一起 */
.hx-nav::after {
  content: "";
  position: absolute; left: 0; right: 0; top: 100%;
  height: 18px; pointer-events: none;
  background: linear-gradient(to bottom, var(--hx-nav-bg), transparent);
}

.hx-brand {
  display: flex; align-items: center; gap: 10px;
  color: var(--hx-ink); text-decoration: none;
  flex: 0 0 auto;
}
/* 品牌标：旋转菱形外环 + 逆向自转的实心内核（视觉静止）。
   26px 方块在 70px 导航里偏重，压到 21px 更秀气；内核 inset 同步收，
   保持「外环细、内核实」的对比度不变。 */
.hx-mark {
  position: relative;
  width: 21px; height: 21px; flex: 0 0 auto;
  border: 1.5px solid var(--hx-acc);
  transform: rotate(45deg);
  animation: hxSpin 11s linear infinite;
  transition: border-color 0.35s var(--hx-ease);
}
.hx-mark::before {
  content: "";
  position: absolute; inset: 6px;
  background: var(--hx-acc);
  animation: hxSpin 11s linear infinite reverse;
}
@keyframes hxSpin { to { transform: rotate(405deg); } }
.hx-brand-t {
  font-family: var(--hx-mono);
  font-size: var(--hx-t21); font-weight: 800; letter-spacing: 0.13em;
  white-space: nowrap;
  transition: color 0.3s var(--hx-ease);
}
/* 后半截用强调色：墨绿/薄荷的双色字标，和菱形标同色系，远看就是一套 */
.hx-brand-t em {
  font-style: normal; font-weight: 500;
  color: var(--hx-acc); letter-spacing: 0.09em;
  font-size: var(--hx-t14-5);
  transition: color 0.3s var(--hx-ease);
}
/* 品牌可点（工具模式下 = 回首页），给一点悬停暗示：后半截提亮一档 */
.hx-brand:hover .hx-brand-t em { color: var(--hx-ink); }

.hx-links { display: flex; gap: clamp(12px, 2vw, 28px); min-width: 0; margin: 0 auto 0 clamp(6px, 2vw, 28px); }
.hx-links a {
  position: relative;
  display: flex; align-items: center; gap: 7px;
  padding: 6px 0;
  font-family: var(--hx-mono); font-size: var(--hx-t12); letter-spacing: 0.16em;
  /* 导航是常用入口，别用三级灰：降到 0.8 不抢戏，但绝对读得清 */
  color: var(--hx-ink); opacity: 0.8; text-decoration: none;
  white-space: nowrap;
  transition: color 0.32s, opacity 0.32s;
}
.hx-links a b { font-weight: 400; font-size: var(--hx-t10); color: inherit; opacity: 0.5; transition: color 0.32s, opacity 0.32s; }
.hx-links a::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 2px; width: 100%;
  background: var(--hx-acc);
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.4s var(--hx-ease);
}
.hx-links a:hover, .hx-links a.is-on { color: var(--hx-ink); opacity: 1; }
.hx-links a:hover b, .hx-links a.is-on b { color: var(--hx-acc); opacity: 1; }
.hx-links a:hover::after, .hx-links a.is-on::after { transform: scaleX(1); }

.hx-search {
  position: relative; /* 实时结果下拉的锚点 */
  display: flex; align-items: center; gap: 9px;
  margin-left: auto;
  width: clamp(150px, 17vw, 236px);
  height: 34px;
  padding: 0 10px;
  background: var(--hx-field-bg);
  border: 1px solid var(--hx-line-2);
  border-radius: 2px;
  transition: border-color 0.25s, background 0.25s;
}
.hx-search:hover { border-color: var(--hx-dim2); }
.hx-search:focus-within { border-color: var(--hx-acc); background: transparent; }
.hx-search svg { width: var(--hx-t14); height: var(--hx-t14); color: var(--hx-dim); flex: 0 0 auto; }
.hx-search input {
  flex: 1; min-width: 0;
  background: transparent; border: 0; outline: none;
  color: var(--hx-ink);
  font-family: var(--hx-mono); font-size: var(--hx-t12); letter-spacing: 0.08em;
  padding: 0;
}
.hx-search input::placeholder { color: var(--hx-dim); letter-spacing: 0.16em; }
.hx-search kbd {
  font-family: var(--hx-mono); font-size: var(--hx-t10);
  color: var(--hx-dim);
  border: 1px solid var(--hx-line-2); border-radius: 2px;
  padding: 1px 5px; line-height: 1.4;
}
/* 已经输入查询词了，「/」快捷键提示就没有存在意义，别占输入宽度 */
.hx-search input:not(:placeholder-shown) ~ kbd { display: none; }

/* ---------- 实时结果下拉（工具页）：等宽小标 + 发丝行 + 薄荷选中条 ---------- */
.hx-sug {
  position: absolute; top: calc(100% + 9px); right: 0; z-index: 90;
  width: min(430px, calc(100vw - 28px));
  background: var(--hx-bg);
  border: 1px solid var(--hx-line-2);
  border-radius: 2px;
  box-shadow: none;
  overflow: hidden;
}
.hx-sug[hidden] { display: none !important; }
.hx-sug-h {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 9px 12px 7px;
  border-bottom: 1px solid var(--hx-line);
  font-family: var(--hx-mono); font-size: var(--hx-t9-5); letter-spacing: 0.22em;
  color: var(--hx-dim2);
}
.hx-sug-h b { color: var(--hx-acc); font-weight: 500; }
.hx-sug-l { max-height: min(56vh, 336px); overflow-y: auto; }
.hx-sug-i {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 1px 10px;
  width: 100%; padding: 9px 12px;
  background: transparent; border: 0; border-bottom: 1px solid var(--hx-line);
  text-align: left; cursor: pointer;
  -webkit-appearance: none; appearance: none;
}
.hx-sug-i:last-child { border-bottom: 0; }
.hx-sug-i.is-on { background: var(--hx-field-bg); box-shadow: inset 2px 0 0 var(--hx-acc); }
.hx-sug-n {
  grid-column: 1; min-width: 0;
  font-size: var(--hx-t13); font-weight: 700; letter-spacing: -0.01em; color: var(--hx-ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hx-sug-d {
  grid-column: 1; min-width: 0;
  font-size: var(--hx-t11); color: var(--hx-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hx-sug-t {
  grid-row: 1 / span 2; grid-column: 2; align-self: center;
  font-family: var(--hx-mono); font-size: var(--hx-t9); letter-spacing: 0.14em;
  color: var(--hx-dim2); white-space: nowrap;
}
.hx-sug-t.is-ext { color: var(--hx-acc); }
/* 个人模块标记（管理员可见，其余人连行都没有） */
.hx-sug-t.is-p { color: var(--hx-acc); }
.hx-sug-f {
  display: flex; align-items: center; gap: 4px;
  padding: 7px 12px 8px;
  border-top: 1px solid var(--hx-line);
  font-family: var(--hx-mono); font-size: var(--hx-t9-5); letter-spacing: 0.1em;
  color: var(--hx-dim2);
}
.hx-sug-f kbd {
  border: 1px solid var(--hx-line-2); border-radius: 2px;
  padding: 0 4px; font-size: var(--hx-t9);
}
.hx-sug-e { padding: 20px 12px; text-align: center; font-size: var(--hx-t12); color: var(--hx-dim); }

.hx-meta {
  display: flex; align-items: center; gap: 7px;
  font-family: var(--hx-mono); font-size: var(--hx-t10-5); letter-spacing: 0.16em;
  color: var(--hx-dim); white-space: nowrap;
}
.hx-meta i {
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--hx-acc);
  /* 呼吸用透明度，不用 box-shadow 扩散（那就是 glow 了） */
  animation: hxBlink 2.8s ease-in-out infinite;
}
@keyframes hxBlink {
  0%, 100% { opacity: 1; }
  55% { opacity: 0.25; }
}

/* 分段控件（设置面板里的「外观」和「列表密度」共用同一个长相）：
   选中态直接反色，和索引行 hover 统一。亮暗开关已经从导航搬进面板，
   导航里带框的只剩两枚：搜索框（输入暗示）、登录（身份操作），
   其余全是幽灵图标钮 —— 再多按钮也不显吵。 */
.hx-seg {
  display: flex;
  height: 30px;
  background: var(--hx-field-bg);
  border: 1px solid var(--hx-line-2);
  border-radius: 2px;
  overflow: hidden;
  flex: none;
}
.hx-seg button {
  -webkit-appearance: none; appearance: none;
  min-width: 27px; height: 100%;
  padding: 0 8px;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--hx-line-2);
  color: var(--hx-dim);
  font-family: var(--hx-mono);
  font-size: var(--hx-t10-5); letter-spacing: 0; line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.16s linear, color 0.16s linear;
}
.hx-seg button:last-child { border-right: 0; }
.hx-seg button:hover { color: var(--hx-ink); }
.hx-seg button.is-on { background: var(--hx-inv-bg); color: var(--hx-inv-ink); }
.hx-seg button:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: -1px; }

/* ---------- 设置弹层（密度 / 亮暗 / 引导 三个低频入口） ----------
   导航只留高频操作；设置是低频入口，幽灵图标钮 + 右对齐小面板。
   首页与工具页都显示：工具页不放密度（无索引可调），但亮暗和引导两边都要用。 */
.hx-set-wrap { position: relative; display: block; flex: none; }
.hx-set {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 2px;
  color: var(--hx-dim);
  cursor: pointer;
  transition: color 0.22s var(--hx-ease), border-color 0.22s var(--hx-ease), background-color 0.35s var(--hx-ease);
}
.hx-set:hover, .hx-set[aria-expanded="true"] { color: var(--hx-acc); }
.hx-set svg { width: var(--hx-t15); height: var(--hx-t15); }
.hx-set:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: 2px; }
.hx-set-panel {
  position: absolute; top: calc(100% + 10px); right: 0;
  width: 276px;
  background: var(--hx-bg);
  border: 1px solid var(--hx-line-2);
  padding: 4px 0 0;
  z-index: 120;
  transform-origin: top right;
  transition: background-color 0.35s var(--hx-ease), border-color 0.35s var(--hx-ease);
}
.hx-set-panel[hidden] { display: none; }
/* 工具页没有索引可调：密度行直接收掉，面板只留外观 + 引导 */
body.hx-tool #hx-dens-row { display: none; }
.hx-set-t {
  display: flex; align-items: baseline; gap: 9px;
  padding: 10px 14px 12px;
  border-bottom: 1px solid var(--hx-line);
  font-size: var(--hx-t13-5); font-weight: 700; color: var(--hx-ink);
}
.hx-set-t span {
  font-family: var(--hx-mono); font-size: var(--hx-t9); font-weight: 400;
  letter-spacing: 0.2em; color: var(--hx-dim2);
}
.hx-set-row {
  display: flex; align-items: center; gap: 12px;
  /* 纵向内边距跟着字号走（横向不动）：大字号下行高变高，固定 10px 会让文字贴住上下分隔线 */
  padding: calc(10px * var(--hx-fsk, 1)) 14px;
}
/* 行与行之间只用发丝线分隔，不再各自留大块空白（面板要矮、要紧凑） */
.hx-set-row + .hx-set-row { border-top: 1px solid var(--hx-line); }
/* 标签只留主名：原来「外观 / 亮色 ／ 暗色」上下两行，下行是纯重复的赘述，
   既撑高行距又占掉半行可点区。解释移到 title，句内状态（排序的当前值）跟在后面同排。 */
.hx-set-l {
  flex: 1 1 auto; min-width: 0;
  font-size: var(--hx-t12-5); color: var(--hx-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hx-set-l i {
  display: inline; margin-left: 7px;
  font-style: normal; font-size: var(--hx-t10); color: var(--hx-dim2);
  font-variant-numeric: tabular-nums;
}
/* 字号滑杆：阅读器式整体缩放，圆点 / 轨道跟随亮暗主题（--hx-acc / --hx-bg / --hx-line-2） */
.hx-fs-range {
  -webkit-appearance: none; appearance: none;
  flex: none; width: 118px; height: 18px; margin: 0;
  background: transparent; cursor: pointer;
}
.hx-fs-range::-webkit-slider-runnable-track { height: 4px; border-radius: 999px; background: var(--hx-line-2); }
.hx-fs-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; margin-top: -5px; border-radius: 50%;
  background: var(--hx-acc); border: 2px solid var(--hx-bg); box-shadow: 0 0 0 1px var(--hx-line-2);
  cursor: pointer;
}
.hx-fs-range::-moz-range-track { height: 4px; border-radius: 999px; background: var(--hx-line-2); }
.hx-fs-range::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--hx-acc); border: 2px solid var(--hx-bg); box-shadow: 0 0 0 1px var(--hx-line-2);
  cursor: pointer;
}
.hx-fs-range:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: 4px; }
/* 引导行：整行就是按钮，悬停底色 + 箭头右移（和索引行同一套反馈语言） */
.hx-set-go {
  -webkit-appearance: none; appearance: none;
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 12px 14px;
  background: transparent;
  border: 0; border-top: 1px solid var(--hx-line);
  color: inherit; font: inherit; text-align: left;
  cursor: pointer;
  /* 非对称按压（Kinetics push button）：松手回弹走 0.42s 弹簧 */
  transition: background-color 0.2s var(--hx-ease), transform 0.42s var(--hx-spring);
}
/* 按下瞬间只给 0.07s——触觉反馈要快，回弹才慢 */
.hx-set-go:active { transform: scale(0.975); transition-duration: 0.07s; }
/* 动作行前置图标：一眼分出「点开去别处」和「就地改值」两类行 */
.hx-set-ico {
  flex: none; display: block; width: 14px; height: 14px;
  color: var(--hx-dim2);
  transition: color 0.2s var(--hx-ease);
}
.hx-set-ico svg { display: block; width: var(--hx-t14); height: var(--hx-t14); }
.hx-set-go .hx-set-l, .hx-set-go .hx-set-l i { transition: color 0.2s var(--hx-ease); }
.hx-set-go-ar {
  flex: none;
  font-style: normal; font-size: var(--hx-t13);
  color: var(--hx-dim2);
  transition: color 0.2s var(--hx-ease), transform 0.24s var(--hx-ease);
}
.hx-set-go:hover { background: var(--hx-field-bg); }
.hx-set-go:hover .hx-set-l { color: var(--hx-ink); }
.hx-set-go:hover .hx-set-ico { color: var(--hx-acc); }
.hx-set-go:hover .hx-set-go-ar { color: var(--hx-acc); transform: translateX(3px); }
.hx-set-go:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: -1px; }

/* ============================================================
   3. Hero
   ============================================================ */
.hx-hero {
  position: relative;
  display: flex; flex-direction: column; justify-content: center;
  min-height: min(80vh, 800px);
  /* 底部留白随字号放大一起加：正文块放大后会变高，固定 52px 会被 SCROLL 提示压住 */
  padding: calc(var(--hx-nav-h) + clamp(28px, 4.4vw, 72px)) var(--hx-pad)
           calc(clamp(28px, 4vw, 52px) + (var(--hx-fsk, 1) - 1) * 46px);
}

.hx-eyebrow {
  font-family: var(--hx-mono);
  font-size: var(--hx-t10-5); letter-spacing: 0.3em;
  color: var(--hx-dim2);
}

.hx-title {
  margin: clamp(14px, 2.4vw, 30px) 0 0;
  font-size: clamp(46px, 11vw, 168px); font-size: round(clamp(46px, 11vw, 168px), 1px);
  font-weight: 800;
  line-height: 0.94;
  letter-spacing: -0.035em;
}
.hx-tl { display: block; padding: 0 0 0.02em; }
/* 描边字：只用来做第二行的层级区分，不是 glow */
.hx-tl-o {
  color: transparent;
  -webkit-text-stroke: 1.6px var(--hx-acc);
  text-stroke: 1.6px var(--hx-acc);
}

.hx-hero-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: clamp(22px, 4vw, 72px);
  margin-top: clamp(22px, 3.6vw, 44px);
}

.hx-desc {
  margin: 0;
  max-width: 40ch;
  font-size: var(--hx-t14); line-height: 2;
  color: var(--hx-dim);
}
.hx-desc b { color: var(--hx-ink); font-weight: 600; }

.hx-stat {
  display: flex; gap: clamp(18px, 3.2vw, 46px);
  margin: 0;
}
.hx-stat div { display: flex; flex-direction: column; gap: 7px; min-width: 0; }
.hx-stat dt {
  font-family: var(--hx-mono);
  font-size: clamp(20px, 2.3vw, 30px); font-size: round(clamp(20px, 2.3vw, 30px), 1px);
  font-weight: 600; line-height: 1;
  color: var(--hx-ink);
  letter-spacing: -0.02em;
}
.hx-stat dd {
  margin: 0;
  font-family: var(--hx-mono);
  font-size: var(--hx-t9-5); letter-spacing: 0.17em;
  color: var(--hx-dim2); white-space: nowrap;
}

.hx-cue {
  position: absolute; left: var(--hx-pad); bottom: clamp(16px, 2.4vw, 26px);
  display: flex; align-items: center; gap: 10px;
  font-family: var(--hx-mono); font-size: var(--hx-t9-5); letter-spacing: 0.3em;
  color: var(--hx-dim2);
}
.hx-cue i {
  display: block; width: 1px; height: 34px;
  background: linear-gradient(to bottom, var(--hx-acc), transparent);
  animation: hxCue 2.4s var(--hx-ease) infinite;
  transform-origin: top;
}
@keyframes hxCue {
  0%, 100% { transform: scaleY(0.25); opacity: 0.4; }
  50% { transform: scaleY(1); opacity: 1; }
}

/* 右侧竖排微标签：填住巨字右侧的空白，同时是编辑式排版的常见手法。
   纯装饰、非阅读文本 —— 高度被 Hero 区限死，跟随字号放大会溢出被裁，
   所以这里局部把 --hx-fsk 钉回 1（下面的 calc 自动退回原尺寸）。 */
.hx-vert {
  position: absolute;
  right: var(--hx-pad); top: 0; bottom: 0;
  display: flex; align-items: center;
  --hx-fsk: 1;
}
.hx-vert span {
  writing-mode: vertical-rl;
  font-family: var(--hx-mono);
  font-size: var(--hx-t9-5); letter-spacing: 0.34em;
  color: var(--hx-dim2);
  border-right: 1px solid var(--hx-line);
  padding-right: 14px;
}

/* ============================================================
   4. 跑马灯条
   ============================================================ */
.hx-strip {
  overflow: hidden;
  padding: 11px 0;
  border-top: 1px solid var(--hx-line);
  border-bottom: 1px solid var(--hx-line);
  background: var(--hx-strip-bg);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.hx-strip-track {
  display: flex; align-items: center;
  width: max-content;
  animation: hxMarquee 52s linear infinite;
}
.hx-strip:hover .hx-strip-track { animation-play-state: paused; }
.hx-strip-track span {
  font-family: var(--hx-mono);
  font-size: var(--hx-t10-5); letter-spacing: 0.22em;
  color: var(--hx-dim2);
  padding: 0 16px; white-space: nowrap;
}
.hx-strip-track i {
  font-style: normal; font-size: var(--hx-t7);
  color: var(--hx-acc); opacity: 0.55;
}
@keyframes hxMarquee { to { transform: translateX(-50%); } }

/* ============================================================
   5. 分类分段 + 索引行
   ============================================================ */
.hx-sec { padding: clamp(34px, 4.4vw, 66px) 0 0; }

/* 分类段头：靠「三档体量」拉层级，不靠加色 ——
   ① 编号做成薄荷描边微章（有形状的元信息）
   ② 大标题纯展示字，重量和字号绝对压场
   ③ 计数与发丝线退到基线以下当注脚，线把「标题 → 计数」串成一条阅读动线 */
.hx-sec-head {
  display: flex; align-items: baseline; gap: clamp(10px, 1.5vw, 20px);
  padding: 0 var(--hx-pad) clamp(16px, 2vw, 26px);
}
.hx-sec-num {
  font-family: var(--hx-mono); font-size: var(--hx-t10-5); letter-spacing: 0.2em;
  color: var(--hx-acc);
  border: 1px solid var(--hx-acc);
  padding: 4px 7px 3px;
  line-height: 1;
  align-self: center;
  flex: none;
}
.hx-sec-head h2 {
  margin: 0;
  font-size: clamp(30px, 4.2vw, 50px); font-size: round(clamp(30px, 4.2vw, 50px), 1px);
  font-weight: 800; letter-spacing: -0.03em; line-height: 1.02;
}
.hx-sec-n {
  font-family: var(--hx-mono); font-size: var(--hx-t10); letter-spacing: 0.2em;
  color: var(--hx-dim2); white-space: nowrap; flex: none;
}
.hx-sec-rule {
  flex: 1; height: 1px; min-width: 24px;
  background: var(--hx-line); align-self: center;
}

/* 密排索引（列数可切：1 / 2 / 3 / 4）----------------------------------------
   列数不写死在媒体查询里，而是 JS 按「用户选的密度 + 当前宽度」算出**有效列数**
   写到 <html data-cols>，CSS 只管按 data-cols 排版。这样 3/4 列在窄屏回退到 2 列时，
   内外边距、轨道数、留白全都自动跟着对，不会出现「列变了但 padding 还按 3 列算」。
   data-tag 单独一位：宽度够且列数 ≤2 时才显示标签列（半幅格子塞不下三段元信息）。 */
.hx-rows {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  border-top: 1px solid var(--hx-line);
}
html[data-cols="1"] .hx-rows { grid-template-columns: 1fr; }
html[data-cols="3"] .hx-rows { grid-template-columns: repeat(3, minmax(0, 1fr)); }
html[data-cols="4"] .hx-rows { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* 只有 1 条的组跨满整行，不留空轨道 */
.hx-rows[data-single] .hx-row { grid-column: 1 / -1; border-right: 0; }
/* 行 / 段会被搜索过滤置 hidden，display:grid 会压过 [hidden]，必须兜住 */
.hx-row[hidden], .hx-sec[hidden] { display: none !important; }

.hx-row {
  -webkit-appearance: none; appearance: none;
  display: grid;
  grid-template-columns: calc(32px * var(--hx-fsk, 1)) minmax(0, 1fr) auto 14px;
  align-items: center;
  gap: clamp(8px, 1.1vw, 14px);
  min-height: 68px;
  /* 纵向内边距随字号放大，横向不动（不让整站重排成窄屏） */
  padding: calc(12px * var(--hx-fsk, 1)) clamp(12px, 1.5vw, 18px) calc(13px * var(--hx-fsk, 1));
  border: 0;
  border-bottom: 1px solid var(--hx-line);
  border-right: 1px solid var(--hx-line);
  background: transparent;
  color: inherit; font: inherit; text-align: left;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.16s linear, color 0.16s linear;
}
/* 有标签列时多给一条轨道（否则箭头会掉进第 4 轨、第 5 轨空着） */
html[data-tag="1"] .hx-row {
  /* 标签列宽度**不跟着字号放大**：它是次要元信息，跟着长会把标题列挤到只剩几个字。
     放大档下标签走省略号，空间优先给标题。 */
  grid-template-columns: calc(32px * var(--hx-fsk, 1)) minmax(0, 1fr) minmax(0, 168px) auto 14px;
}

/* 内外边距按有效列数贴边：首列贴左缘、末列贴右缘、中线留双倍内边距，反色才能铺满整条边 */
html[data-cols="1"] .hx-row {
  padding-left: var(--hx-pad);
  padding-right: var(--hx-pad);
  border-right: 0;
}
html[data-cols="2"] .hx-row:nth-child(odd) { padding-left: var(--hx-pad); }
html[data-cols="2"] .hx-row:nth-child(even) { padding-right: var(--hx-pad); border-right: 0; }
html[data-cols="3"] .hx-row:nth-child(3n + 1) { padding-left: var(--hx-pad); }
html[data-cols="3"] .hx-row:nth-child(3n) { padding-right: var(--hx-pad); border-right: 0; }
html[data-cols="4"] .hx-row:nth-child(4n + 1) { padding-left: var(--hx-pad); }
html[data-cols="4"] .hx-row:nth-child(4n) { padding-right: var(--hx-pad); border-right: 0; }
html[data-single] .hx-row { padding-right: var(--hx-pad); }

/* 3 列：再压一档，标签让位、状态收成点 */
html[data-cols="3"] .hx-row {
  min-height: 58px;
  padding-top: calc(9px * var(--hx-fsk, 1)); padding-bottom: calc(10px * var(--hx-fsk, 1));
  gap: 10px;
}
html[data-cols="3"] .hx-row-n { font-size: var(--hx-t14-5); }
/* 高密度下标题也收一档，否则"大标题 + 46px 细行"的比例会失衡 */
html[data-cols="3"] .hx-sec { padding-top: clamp(28px, 3.4vw, 48px); }
html[data-cols="3"] .hx-sec-head h2 { font-size: clamp(24px, 3vw, 38px); font-size: round(clamp(24px, 3vw, 38px), 1px); }
html[data-cols="4"] .hx-sec { padding-top: clamp(22px, 2.6vw, 38px); }
html[data-cols="4"] .hx-sec-head h2 { font-size: clamp(21px, 2.4vw, 30px); font-size: round(clamp(21px, 2.4vw, 30px), 1px); }

/* 页头随密度联动 ------------------------------------------------------------
   选高密度的人是想"一屏看更多"，页头就不该再占满一屏。
   1/2 列保持海报级 Hero（这套皮肤的标识），3/4 列压成页头，并收起跑马灯
   —— 跑马灯滚的就是下面正在列的工具名，密集视图里纯属重复。 */
html[data-cols="3"] .hx-hero {
  min-height: 64vh;
  padding-top: calc(var(--hx-nav-h) + clamp(26px, 4vw, 62px));
  padding-bottom: clamp(22px, 3.2vw, 42px);
}
html[data-cols="3"] .hx-title { font-size: clamp(38px, 7vw, 106px); font-size: round(clamp(38px, 7vw, 106px), 1px); }
html[data-cols="3"] .hx-hero-foot { margin-top: clamp(16px, 2.4vw, 34px); }
html[data-cols="3"] .hx-strip { display: none; }
html[data-cols="3"] .hx-cue { display: none; }

html[data-cols="4"] .hx-hero {
  min-height: 50vh;
  padding-top: calc(var(--hx-nav-h) + clamp(20px, 3vw, 48px));
  padding-bottom: clamp(18px, 2.6vw, 34px);
}
html[data-cols="4"] .hx-title { font-size: clamp(32px, 5.4vw, 84px); font-size: round(clamp(32px, 5.4vw, 84px), 1px); }
html[data-cols="4"] .hx-hero-foot { margin-top: clamp(14px, 2vw, 26px); }
html[data-cols="4"] .hx-desc { font-size: var(--hx-t13); line-height: 1.85; }
html[data-cols="4"] .hx-stat dt { font-size: clamp(17px, 1.8vw, 24px); font-size: round(clamp(17px, 1.8vw, 24px), 1px); }
html[data-cols="4"] .hx-strip { display: none; }
html[data-cols="4"] .hx-cue { display: none; }
/* 竖排标签高度跟着 Hero 缩，46vh 时会被裁，干脆不出 */
html[data-cols="3"] .hx-vert,
html[data-cols="4"] .hx-vert { display: none; }
html[data-cols="3"] .hx-row-d { font-size: var(--hx-t11); }

/* 4 列：极密模式，只留「编号 + 名称 + 状态点 + 箭头」，一句话收进 title 提示。
   行高从 46px 提到 66px：名称单行也要有呼吸感，46px 在宽屏上显得挤扁 */
html[data-cols="4"] .hx-row {
  grid-template-columns: calc(20px * var(--hx-fsk, 1)) minmax(0, 1fr) auto 12px;
  min-height: 66px;
  padding-top: 12px; padding-bottom: 13px;
  gap: 8px;
}
html[data-cols="4"] .hx-row-i { font-size: var(--hx-t9-5); letter-spacing: 0; }
html[data-cols="4"] .hx-row-n { font-size: var(--hx-t14-5); }
html[data-cols="4"] .hx-row-d { display: none; }

html[data-tag="0"] .hx-row-tag { display: none; }
html[data-tag="0"] .hx-row-st b { display: none; }
/* 单列时宽度足够，状态文字再放回来（特异性要压过上面 data-tag=0 的隐藏） */
html[data-tag="0"][data-cols="1"] .hx-row-st b { display: inline; }

.hx-row-i {
  font-family: var(--hx-mono);
  font-size: var(--hx-t10-5); letter-spacing: 0.08em;
  color: var(--hx-dim2);
  transition: color 0.16s linear;
}
.hx-row-body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* 名字行：名字 + 「个人」chip 同一基线上（chip 不许被压扁、名字过长仍省略） */
.hx-row-nh { display: flex; align-items: center; gap: 8px; min-width: 0; }
.hx-row-nh > .hx-row-n { min-width: 0; }
.hx-row-n {
  font-size: var(--hx-t15-5); font-weight: 650; letter-spacing: -0.01em;
  line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.hx-row-d {
  font-size: var(--hx-t11-5); line-height: 1.55;
  color: var(--hx-dim);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color 0.16s linear;
}
/* 标签列：把「描述结束 → 状态点」之间那段空白填成信息，而不是留气 */
.hx-row-tag {
  font-family: var(--hx-mono);
  font-size: var(--hx-t9-5); letter-spacing: 0.08em;
  color: var(--hx-dim2);
  text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color 0.16s linear;
}
.hx-row-st {
  display: flex; align-items: center; gap: 6px;
  font-family: var(--hx-mono);
  font-size: var(--hx-t8-5); letter-spacing: 0.14em;
  color: var(--hx-dim2);
  white-space: nowrap;
  transition: color 0.16s linear;
}
.hx-row-st b { font-weight: 400; }
.hx-row-st i {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--hx-acc);
  transition: background 0.16s linear;
}
.hx-row-st.is-ext i { background: transparent; border: 1px solid var(--hx-dim2); }
.hx-row-st.is-wip i { background: var(--hx-dim2); }
/* 个人模块 chip：只有管理员看得到（条目由 helix-home.js 门禁控制），
   薄荷描边小徽 —— 一眼认出「这条是私人的」，和段头编号徽同一语言 */
.hx-row-p {
  flex: 0 0 auto;
  align-self: center;
  font-family: var(--hx-mono);
  font-size: var(--hx-t8-5); letter-spacing: 0.14em;
  color: var(--hx-acc);
  border: 1px solid var(--hx-acc);
  border-radius: 2px;
  padding: 2px 5px 1px;
  white-space: nowrap;
  transition: color 0.16s linear, border-color 0.16s linear;
}
/* 4 列最紧的一档 chip 让位（名字优先） */
html[data-cols="4"] .hx-row-p,
html[data-tag="0"] .hx-row-p { display: none; }
.hx-row:hover .hx-row-p,
.hx-row:focus-visible .hx-row-p { color: var(--hx-inv-ink); border-color: var(--hx-inv-ink); }

.hx-row-ar {
  justify-self: end;
  font-size: var(--hx-t13); color: var(--hx-dim2);
  /* 箭头用弹簧：hover 时甩出去再轻轻收回，比匀速位移多一份重量 */
  transition: transform 0.42s var(--hx-spring), color 0.16s linear;
}

/* 主交互：整行反色 */
.hx-row:hover,
.hx-row:focus-visible {
  background: var(--hx-inv-bg);
  color: var(--hx-inv-ink);
  outline: none;
}
.hx-row:hover .hx-row-i,
.hx-row:hover .hx-row-tag,
.hx-row:hover .hx-row-st,
.hx-row:hover .hx-row-ar,
.hx-row:focus-visible .hx-row-i,
.hx-row:focus-visible .hx-row-tag,
.hx-row:focus-visible .hx-row-st,
.hx-row:focus-visible .hx-row-ar { color: var(--hx-inv-dim); }
.hx-row:hover .hx-row-d,
.hx-row:focus-visible .hx-row-d { color: var(--hx-inv-dim); }
.hx-row:hover .hx-row-st i,
.hx-row:focus-visible .hx-row-st i { background: var(--hx-inv-ink); }
.hx-row:hover .hx-row-st.is-ext i,
.hx-row:focus-visible .hx-row-st.is-ext i { background: transparent; border-color: var(--hx-inv-ink); }
.hx-row:hover .hx-row-ar,
.hx-row:focus-visible .hx-row-ar { transform: translateX(6px); }

/* 无结果 */
.hx-none {
  padding: clamp(52px, 7vw, 96px) var(--hx-pad);
  border-top: 1px solid var(--hx-line);
}
.hx-none p { margin: 14px 0 0; font-size: var(--hx-t13); color: var(--hx-dim); }
.hx-none button {
  -webkit-appearance: none; appearance: none;
  background: transparent; border: 0; padding: 0;
  color: var(--hx-acc); font: inherit; cursor: pointer;
  border-bottom: 1px solid var(--hx-acc);
}

/* ============================================================
   6. OUTRO
   ============================================================ */
.hx-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto);
  gap: clamp(22px, 4vw, 64px);
  align-items: start;
  margin-top: clamp(60px, 8vw, 132px);
  padding: clamp(36px, 5.4vw, 76px) var(--hx-pad) clamp(26px, 3.6vw, 44px);
  border-top: 1px solid var(--hx-line);
}
.hx-foot-t {
  font-size: clamp(38px, 7vw, 100px); font-size: round(clamp(38px, 7vw, 100px), 1px);
  font-weight: 800; line-height: 0.9; letter-spacing: -0.04em;
}
.hx-foot-t em {
  font-style: normal;
  color: transparent;
  -webkit-text-stroke: 1.4px var(--hx-dim2);
  text-stroke: 1.4px var(--hx-dim2);
}
.hx-foot-col { display: grid; gap: 14px; margin: 0; }
.hx-foot-col div { display: flex; flex-direction: column; gap: 5px; }
.hx-foot-col dt {
  font-family: var(--hx-mono);
  font-size: var(--hx-t9); letter-spacing: 0.22em; color: var(--hx-dim2);
}
.hx-foot-col dd { margin: 0; font-size: var(--hx-t12); color: var(--hx-dim); }
.hx-foot-c {
  grid-column: 1 / -1;
  display: flex; justify-content: space-between; gap: 14px; flex-wrap: wrap;
  margin: clamp(22px, 3.4vw, 44px) 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--hx-line);
  font-family: var(--hx-mono);
  font-size: var(--hx-t9-5); letter-spacing: 0.16em; color: var(--hx-dim2);
}

/* ============================================================
   7. 入场动画（IntersectionObserver 挂 .in）
   ============================================================ */
.hx-rev {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.7s var(--hx-ease), transform 0.7s var(--hx-ease);
  transition-delay: var(--d, 0s);
}
.hx-rev.in { opacity: 1; transform: none; }

/* Hero 首屏不等观察器，直接播（避免首帧空白） */
.hx-hero .hx-eyebrow,
.hx-hero .hx-tl,
.hx-hero .hx-desc,
.hx-hero .hx-stat {
  animation: hxUp 0.9s var(--hx-ease) both;
}
.hx-hero .hx-eyebrow { animation-delay: 0.05s; }
.hx-hero .hx-tl:nth-child(1) { animation-delay: 0.12s; }
.hx-hero .hx-tl:nth-child(2) { animation-delay: 0.24s; }
.hx-hero .hx-desc { animation-delay: 0.4s; }
.hx-hero .hx-stat { animation-delay: 0.48s; }
@keyframes hxUp {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

/* ============================================================
   7.5 过渡动效（视图切换 / 弹窗 / 内容替换）
   ------------------------------------------------------------
   原则：短、轻、只动一次。页面级切换（首页 ↔ 工具）两边都只用淡入：
   `.hx` 带 position:fixed 的背景层伪元素和进度条、`#legacy-app` 带
   sticky/fixed 工具条，一旦给容器加 transform，fixed 子孙会临时改
   包含块（进度条下坠、背景层瞬间铺满全页），所以位移只敢用在没有
   fixed 子孙的元素上（弹窗面板、索引行、下拉）。
   弹窗开 = 遮罩淡入 + 面板弹簧落位；关 = 快出 0.12-0.15s 后 hidden（JS 挂 is-out）。
   非对称时序：入场慢且有重量（spring 0.34s），退场快（≤0.15s）——
   参考 Kinetics「Motion that has weight」：落位带过冲回落，离开不拖泥带水。
   全部动画在 prefers-reduced-motion 下关闭（见第 9 节）。 */
@keyframes hxFade { from { opacity: 0; } to { opacity: 1; } }
/* 落位用弹簧：起点压低 6%、上抬 14px，spring 曲线收尾时轻微过冲再回落，
   面板有"掉下来站稳"的重量感（Kinetics: spring pop，0.34s 基准） */
@keyframes hxPopIn {
  from { opacity: 0; transform: translateY(-14px) scale(0.94); }
  to { opacity: 1; transform: none; }
}
@keyframes hxPopOut {
  from { opacity: 1; transform: none; }
  to { opacity: 0; transform: translateY(-6px) scale(0.99); }
}
@keyframes hxMaskOut { from { opacity: 1; } to { opacity: 0; } }
@keyframes hxSugIn {
  from { opacity: 0; transform: translateY(-8px); }
  to { opacity: 1; transform: none; }
}
@keyframes hxRowIn {
  from { opacity: 0; transform: translateY(7px); }
  to { opacity: 1; transform: none; }
}

/* 页面级切换：首页根 / 旧站壳（JS 在显隐后挂 .hx-enter，播完即摘） */
.hx.hx-enter { animation: hxFade 0.24s var(--hx-ease) both; }
#legacy-app.hx-enter { animation: hxFade 0.22s var(--hx-ease) both; }
/* 工具之间互相跳转：只淡入，不做位移（视图内部工具条不抖） */
#legacy-app .view.hx-enter { animation: hxFade 0.2s var(--hx-ease) both; }

/* 大弹窗：开（CSS :not([hidden]) 自动播）/ 关（JS 加 .is-out，150ms 后 hidden） */
.hx-sw-mask:not([hidden]) { animation: hxFade 0.18s var(--hx-ease) both; }
.hx-sw-mask:not([hidden]) .hx-sw-modal { animation: hxPopIn 0.34s var(--hx-spring) both; }
.hx-sw-mask.is-out { animation: hxMaskOut 0.15s var(--hx-ease) both; }
.hx-sw-mask.is-out .hx-sw-modal { animation: hxPopOut 0.15s var(--hx-ease) both; }

/* 设置弹层 / 搜索下拉：同类轻弹 */
.hx-set-panel:not([hidden]) { animation: hxPopIn 0.34s var(--hx-spring) both; }
.hx-set-panel.is-out { animation: hxPopOut 0.12s var(--hx-ease) both; }
.hx-sug:not([hidden]) { animation: hxSugIn 0.28s var(--hx-slide) both; }

/* 内容替换：筛选后新出现的行 / 分类段 / 空态（JS 挂 .hx-in，260ms 后摘） */
.hx-row.hx-in, .hx-sec.hx-in { animation: hxRowIn 0.26s var(--hx-ease) both; }
.hx-none:not([hidden]) { animation: hxRowIn 0.26s var(--hx-ease) both; }

/* 主题切换：大表面颜色渐变过渡，小控件靠各自的 color/border 过渡。
   body 必须带 html[data-skin="helix"] 前缀：index.html 也加载本文件，
   裸 body 选择器会给旧站整页挂上过渡，干扰那边的主题测试 */
html[data-skin="helix"] body, .hx, #legacy-app, .hx-sw-modal, .hx-sug {
  transition: background-color 0.35s var(--hx-ease), border-color 0.35s var(--hx-ease);
}

/* ============================================================
   8. 响应式
   ============================================================ */
/* 列数 / 贴边 / 是否显示标签，全部由 JS 算出的 data-cols、data-tag 决定，
   这里只留与列数无关的部分（导航、Hero、页脚），避免两套规则互相打架 */

@media (max-width: 1180px) {
  /* 导航控件整体加大后，1180 以下塞不下三个分类链接 */
  .hx-links { display: none; }
  .hx-vert { display: none; }
}

@media (max-width: 980px) {
  .hx-search { margin-left: auto; }
  .hx-hero { min-height: min(70vh, 640px); }
  .hx-hero-foot { grid-template-columns: minmax(0, 1fr); align-items: start; }
  .hx-stat { flex-wrap: wrap; gap: 18px 30px; }
}

/* 单列时行更宽，字号可以放大一档，不必为省空间挤成小字 */
@media (max-width: 900px) {
  html[data-cols="1"] .hx-row { min-height: 64px; }
  html[data-cols="1"] .hx-row-n { font-size: var(--hx-t15); }
  html[data-cols="1"] .hx-row-d { font-size: var(--hx-t11-5); }
}

@media (max-width: 720px) {
  .hx-meta { display: none; }
  /* 手机上设置钮必须留着：亮暗和功能引导都收进面板了，收掉它就没有换肤入口。
     密度行在窄屏没意义（强制单列），面板里靠 data-cols 自动回退即可，行本身照常显示 */
  .hx-nav { gap: 12px; }
  /* 980 断点那条 margin-left:auto 会和 flex:1 打架：auto 边距先吃掉全部空余，
     再把搜索框往后顶，切换键就被推出视口了。手机端必须归零。 */
  .hx-search { width: 0; flex: 1 1 0; margin-left: 0; min-width: 0; }
  /* 品牌只留菱形标：文字让位给「返回 + 工具名 + 搜索 + 设置 + 登录」，
     390px 下这一排一个都少不了（原来品牌文字 + 切换键会把登录键压成 0 宽） */
  .hx-brand-t { display: none; }
  .hx-brand { gap: 0; }
  /* 手机上不撑满屏：Hero 内容本身够高，硬撑 82vh 会在数据块下面留一大片空 */
  .hx-hero {
    min-height: auto;
    padding-top: calc(var(--hx-nav-h) + 46px);
    padding-bottom: 30px;
  }
  .hx-title { font-size: clamp(40px, 13vw, 76px); font-size: round(clamp(40px, 13vw, 76px), 1px); }
  .hx-tl-o { -webkit-text-stroke-width: 1.1px; }
  .hx-desc { font-size: var(--hx-t13-5); line-height: 1.95; }
  .hx-stat {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 24px;
  }
  /* 字号放大后说明小标（nowrap）会横向撑出格子、压到右边一列的文字上，窄屏允许换行 */
  .hx-stat dd { white-space: normal; overflow-wrap: anywhere; }
  .hx-foot { grid-template-columns: minmax(0, 1fr); }
  .hx-cue { display: none; }
  .hx-foot-t { font-size: clamp(34px, 12vw, 64px); font-size: round(clamp(34px, 12vw, 64px), 1px); }
}

/* 极窄屏：幽灵图标钮收一档（30px），返回键也收成纯箭头，别把面包屑和搜索框挤出去 */
@media (max-width: 560px) {
  .hx-sw, .hx-set { width: 30px; height: 30px; }
  .hx-crumb-b { height: 30px; }
  .hx-crumb-b span { display: none; }
  .hx-crumb-b { padding: 0 8px; }
  /* 登录键在用户机器上会 Reveal（沙箱里 CDN 被墙才不显示）——按可见做最坏排版：
     导航内边距收一档，搜索框保 64px 下限，剩下的让面包屑标题省略 */
  .hx-nav { padding: 0 12px; }
  .hx-search { min-width: 64px; }
  /* 极窄屏下面板贴右边会被裁，改成左右各让 12px 的浮层 */
  .hx-set-panel { width: min(276px, calc(100vw - 24px)); right: -46px; }
}

/* ============================================================
   9. 降级
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .hx-mark,
  .hx-mark::before,
  .hx-meta i,
  .hx-cue i,
  .hx-strip-track,
  .hx-hero .hx-eyebrow,
  .hx-hero .hx-tl,
  .hx-hero .hx-desc,
  .hx-hero .hx-stat { animation: none !important; }
  /* 7.5 节全部过渡动效：视图进入 / 弹窗 / 下拉 / 行出现，一律直出 */
  .hx.hx-enter, #legacy-app.hx-enter, #legacy-app .view.hx-enter,
  .hx-sw-mask, .hx-sw-mask .hx-sw-modal,
  .hx-set-panel, .hx-sug,
  .hx-row.hx-in, .hx-sec.hx-in, .hx-none:not([hidden]) { animation: none !important; }
  .hx-rev { opacity: 1; transform: none; transition: none; }
  .hx-row, .hx-row-ar { transition: none; }
}

/* ============================================================
   10. 工具视图皮肤（只在 #legacy-app 内生效，首页不受影响）
   ------------------------------------------------------------
   工具页有 12 个视图、各自一份 css（tools / resize-tool / web-spec /
   guide / gomoku / icons…），逐个重写不现实也不该做。
   这里只做两件事，把"同一套皮肤"落到所有页面上：
   1) 改结构令牌：圆角收到 2-3px、去掉投影、控件压到 32px —— 各视图本来
      就是读 --r-card / --r-btn / --shadow-1 的，改一处全站方角。
   2) 重写公共外壳：页头、返回键、主按钮、拖放区、输入框、分组标题、侧栏。
      各页内部细节保持原样，视觉语言已经跟着一致。
   ============================================================ */
#legacy-app {
  --r-card: 3px;
  --r-btn: 2px;
  /* 不能写 none：gomoku.css:722 是 `var(--shadow-1), inset …` 的多值写法，
     none 混进列表会让整条声明失效，连带丢掉那个 2px 内嵌环。 */
  --shadow-1: 0 0 0 rgba(0, 0, 0, 0);
  --ctl-h: 32px;
  --ctl-px: 12px;
}


/* ---------- 页头：已删除 ----------
   各工具页的「PIXEL WORKSHOP / TOOL + 工具名 + 返回」是全局导航面包屑的纯重复，
   2026-10-22 从 helix.html 全部移除；视图内只留一枚隐藏 .btn-back 作代理点击目标
   （见第 11 节 .hx-ghost）。2026-10-23 图标工坊的项目面包屑也并进工具栏，
   全站工具页视图内已无页头。 */

/* ---------- 主按钮 = 薄荷反色（和首页行 hover 同一套） ---------- */
#legacy-app .view .btn-p,
#legacy-app .view .btn.primary {
  background: var(--hx-inv-bg);
  border-color: var(--hx-inv-bg);
  color: var(--hx-inv-ink);
  font-weight: 700;
}
#legacy-app .view .btn-p:hover,
#legacy-app .view .btn.primary:hover {
  background: var(--hx-inv-bg);
  border-color: var(--hx-inv-bg);
  color: var(--hx-inv-ink);
  filter: brightness(1.1);
}

/* ---------- 拖放区：虚线换成发丝实线，提示语改等宽 ----------
   各视图的拖放区类名不统一：融合视图是 .drop，SVG 清理是 #dz，
   尺寸调整是 #rzDrop，批量抠图是 .cxo-dropzone。
   四个都要覆盖，否则会出现"有的页虚线有的页实线""有的页白卡有的页透明"。 */
#legacy-app .drop,
#legacy-app #dz,
#legacy-app #rzDrop,
#legacy-app .cxo-dropzone {
  border: 1px solid var(--hx-line-2);
  background: transparent;
  box-shadow: none;
}
#legacy-app .drop:hover, #legacy-app .cxo-dropzone:hover { border-color: var(--hx-dim2); background: var(--hx-field-bg); }
#legacy-app .drop.over, #legacy-app .cxo-dropzone.over { border-color: var(--hx-acc); background: var(--hx-field-bg); }
#legacy-app .drop-icon, #legacy-app .cxo-dropzone .drop-icon {
  border-radius: 2px;
  background: var(--hx-field-bg);
  border: 1px solid var(--hx-line-2);
  color: var(--hx-dim);
}
/* 抠图的副标题用 .t2，不是 .drop-t2，这里补一份等宽排版 */
#legacy-app .drop-t2, #legacy-app .cxo-dropzone .t2 {
  font-family: var(--hx-mono);
  font-size: var(--hx-t10-5); letter-spacing: 0.08em;
}

/* ---------- 分组标题：左侧 2px 薄荷短杠，替代原来靠字号区分的做法 ---------- */
#legacy-app .group h3,
#legacy-app .group-head h2 {
  padding-left: 9px;
  border-left: 2px solid var(--hx-acc);
  font-size: var(--hx-t13); font-weight: 700; letter-spacing: 0.01em;
  line-height: 1.3;
}
#legacy-app .group-desc { letter-spacing: 0.02em; }

/* ---------- 输入类：方角 + 浅底 + 发丝边；聚焦走中性灰（沿用站点规矩，不把主题色带进表单） ---------- */
#legacy-app input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
#legacy-app select,
#legacy-app textarea {
  border-radius: 2px;
  background: var(--hx-field-bg);
  border: 1px solid var(--hx-line-2);
  color: var(--text);
}
#legacy-app input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]):focus,
#legacy-app select:focus,
#legacy-app textarea:focus {
  outline: none;
  border-color: var(--text-3);
}
/* 组合型搜索框（图标工坊 #ic-q / 网页规范 #wsFilter）：容器本身就是那一个框，
   里面的 input 不能再画一层 —— 否则就是「框里套框」的双线，浅色主题下尤其像系统默认控件。
   通用 input 规则特异性是 (1,4,1)（四个 :not([type])），这里必须叠两个 id 才压得过。 */
#legacy-app #view-icons .ic-search input,
#legacy-app #view-icons .ic-search input:focus,
#legacy-app #view-spec .ws-search input,
#legacy-app #view-spec .ws-search input:focus {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* 字也跟顶部搜索同一套：等宽 + 紧字距，工具页里不再另起一种观感 */
#legacy-app #view-icons .ic-search input,
#legacy-app #view-spec .ws-search input {
  font-family: var(--hx-mono);
  font-size: var(--hx-t11-5);
  letter-spacing: 0.04em;
}
#legacy-app #view-icons .ic-search input::placeholder,
#legacy-app #view-spec .ws-search input::placeholder { color: var(--hx-dim); }
#legacy-app .badge,
#legacy-app .info-chips > * { border-radius: 2px; }

/* ---------- 滚动条：细、方、低对比 ---------- */
#legacy-app *::-webkit-scrollbar { width: 9px; height: 9px; }
#legacy-app *::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 0;
  border: 2px solid transparent;
  background-clip: content-box;
}
#legacy-app *::-webkit-scrollbar-thumb:hover { background: var(--text-3); background-clip: content-box; }

/* ============================================================
   11. 工具页统一顶栏
   ------------------------------------------------------------
   导航从 .hx 里提出来，做成 body 级的全局固定条：首页和工具页共用
   同一条（工具页多一枚「返回 / 工具名」面包屑）。旧侧栏已于 2026-10-24
   连同 DOM 一起删除（不再是隐藏，是不存在）。
   代价：所有依赖 100vh 或 sticky 的视图要减掉导航高度，下面统一处理。
   ============================================================ */
#legacy-app .main { padding-top: var(--hx-nav-h); }

/* 全屏高度的视图：减掉导航高度，避免溢出 70px 产生双滚动条。
   单图处理 2026-10-30 下午起也并进来（用户要求「tool-body 高度自适应、内容也要变高」），
   它内部按 flex column 把剩余高度分给预览/参数三栏，不再自然流留一大片空白。 */
#legacy-app #view-anim,
#legacy-app #view-frames,
#legacy-app #view-cut,
#legacy-app #view-image { height: calc(100vh - var(--hx-nav-h)); }
/* 窄屏（≤960）：单图处理退回自然流 —— 三栏堆叠成单列后一屏装不下，
   锁死视口高会把预览反复压扁（历史上已踩过），这里必须显式解除。
   ⚠️ 选择器要与上一行同特异性且写在后面，否则压不住。 */
@media (max-width: 960px) {
  #legacy-app #view-image { height: auto; }
}

/* 图标工坊里还有几个 10-12px 圆角的旧件（标签页/分类项），一并收方。
   ⚠️ 圆角口径：内部块圆角必须小于外框圆角。外框收到 2px，内部 .ic-tab 原本还是 7px
   → 内部圆角远大于外框，选中块四角会顶出外框轮廓。这里把内部 tab 一并收成 0
   （外框 2px − 内边距 3px 已无余量，直角才不违例），与 helix 的方角语言一致。 */
#legacy-app #view-icons .ic-tabs,
#legacy-app #view-icons .ic-detail,
#legacy-app #view-icons .ic-pcard { border-radius: 2px; }
#legacy-app #view-icons .ic-tab { border-radius: 0; }

/* sticky 元素下沉到导航之下 */
#legacy-app #view-icons .ic-toolbar { top: var(--hx-nav-h); }
#legacy-app #view-icons .ic-side,
#legacy-app #view-icons .ic-detail { top: calc(var(--hx-nav-h) + 16px); }
#legacy-app #view-icons .ic-detail { max-height: calc(100vh - var(--hx-nav-h) - 32px); }
#legacy-app #view-icons .ic-cat-list { max-height: calc(100vh - var(--hx-nav-h) - 220px); }
/* 规范页旧顶栏已删：目录贴导航下沉，不用再给顶栏留 86px */
#legacy-app #view-spec .ws-toc { top: calc(var(--hx-nav-h) + 16px); max-height: calc(100vh - var(--hx-nav-h) - 32px); }
/* 规范页左侧目录：旧皮肤用「浅灰块 + Arco 蓝竖线」标记当前位置，在 helix 下是异类
   （全站唯一的蓝色 UI）。换成皮肤主语言：当前位置 = 整行反色（薄荷底 / 近黑字），
   hover 只给浅底，常态去装饰线、只留文字层级。 */
html[data-skin="helix"] #view-spec .ws-toc a {
  border-left: 0; border-bottom: 0;
  padding: 6px 10px;
  color: var(--hx-dim);
  transition: background .15s var(--ease), color .15s var(--ease);
}
html[data-skin="helix"] #view-spec .ws-toc a:hover { color: var(--hx-ink); background: var(--hx-field-bg); }
html[data-skin="helix"] #view-spec .ws-toc a.on,
html[data-skin="helix"] #view-spec .ws-toc a.on:hover {
  background: var(--hx-inv-bg);
  color: var(--hx-inv-ink);
  border-color: transparent;
  font-weight: 700;
}
html[data-skin="helix"] #view-spec .ws-toc-group-t,
html[data-skin="helix"] #view-spec .ws-toc-sub-t { color: var(--hx-dim2); }
/* 规范页搜索框移进页面工具条后的尺寸（helix 下由 web-spec.js 搬迁） */
#legacy-app #view-spec .tk-toolbar .ws-search input { width: min(240px, 38vw); }
/* 旧顶栏原本用自身 padding 提供 14px 顶部间距（tool-body 顶 padding 是 0），删了要补 */
#legacy-app #view-spec .tool-body { padding-top: 18px; }

/* 视图内原来的返回键收进顶栏面包屑（保留在 DOM 里，作为代理点击目标） */
#legacy-app .btn-back,
#legacy-app .hx-ghost { display: none !important; }
/* 规范页搜索框的常驻停放态（移入工具条前不可见；类名被 JS 摘掉即现身） */
#legacy-app .ws-parked { display: none; }
/* PDF 功能条原本贴在旧页头下方（自带 14px 上边距）；页头删了，归零，顶距与其他工具一致 */
#legacy-app #view-pdfcompress .pc-fnbar { margin-top: 0; }
/* 图标工坊：视图内页头已删（2026-10-23），项目名并进工具栏最左，此处不再需要空条兜底 */

/* ---------- 面包屑（只在工具页出现） ---------- */
.hx-crumb { display: flex; align-items: center; gap: 10px; min-width: 0; }
.hx-crumb[hidden] { display: none !important; }
.hx-crumb-b {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 8px 0 6px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 2px;
  color: var(--hx-ink); opacity: 0.82;
  font-family: var(--hx-mono);
  font-size: var(--hx-t11); letter-spacing: 0.1em;
  cursor: pointer;
  transition: color 0.22s var(--hx-ease), opacity 0.22s var(--hx-ease), border-color 0.22s var(--hx-ease), background-color 0.35s var(--hx-ease);
}
.hx-crumb-b svg { width: var(--hx-t13); height: var(--hx-t13); }
.hx-crumb-b:hover { color: var(--hx-acc); opacity: 1; }
.hx-crumb-b:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: 2px; }
.hx-crumb-s { color: var(--hx-dim2); font-family: var(--hx-mono); font-size: var(--hx-t11); }
.hx-crumb-t {
  min-width: 0;
  font-size: var(--hx-t13-5); font-weight: 700; letter-spacing: -0.01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* 工具模式下：收起首页专属控件（分类链接 / 计数），搜索改成"回首页筛选"。
   设置钮两边都留着 —— 亮暗和功能引导现在只从面板进，工具页也需要。 */
body.hx-tool .hx-links,
body.hx-tool .hx-meta { display: none; }
body.hx-tool .hx-search { margin-left: auto; }

/* ---------- 导航里的账号键（从旧侧栏搬来） ---------- */
.hx-acct { display: flex; align-items: center; flex: none; }
.hx-acct .wb-account {
  height: 34px; padding: 0 12px;
  background: var(--hx-field-bg);
  border: 1px solid var(--hx-line-2);
  border-radius: 2px;
  color: var(--hx-ink);
  font-family: var(--hx-mono);
  font-size: var(--hx-t11); letter-spacing: 0.08em;
  cursor: pointer;
  transition: border-color 0.22s, color 0.22s, background-color 0.35s var(--hx-ease);
}
.hx-acct .wb-account:hover { border-color: var(--hx-acc); color: var(--hx-acc); }

/* ---------- 等宽位置里的「中文」不要继承等宽栈 ----------
   导航里「字和图标对不齐」的真凶不是图标，是中文的行盒度量：
   · 等宽栈的首字体（ui-monospace / Consolas）ascent≈0.93em、descent≈0.29em；
     中文只有「字形」来自回退字体（苹方 / 雅黑，字面≈1.06em），行盒度量仍按首字体算。
   · 半行距上下均分 → 中文被整体上提 ≈0.1em：14px 时 1.5px、22px 时 2.4px
     （字号越大越明显，所以把字号调大后更刺眼）。
   · 图标是几何居中，于是「图标看着坐低、字往上飘」。
   修法：等宽位置里放中文（返回 / 登录 / 分类名）就把字体换回 --hx-sans ——
   中文字形同源、字号字距都不变，只是把行盒度量换成正主；纯 ASCII 的等宽微标不受影响。
   实测（1282 宽 / 字号 18px）：返回、登录 由「高于图标 1.5px」收到 0.5px 以内。
   ⚠️ 这段必须放在 .hx-acct .wb-account 之后：同权重，靠顺序生效。 */
.hx-crumb-b span,
.hx-acct .wb-account,
.hx-links a { font-family: var(--hx-sans); }
/* 分类链接里的序号（01 / 02）仍是数字微标，留在等宽栈里 */
.hx-links a b { font-family: var(--hx-mono); }

/* ---------- 工具切换（补旧侧栏的横向跳转） ----------
   图标钮贴在品牌旁，只在工具模式出现：首页有整幅分类索引，不需要它；
   工具页侧栏没了，工具间跳转只剩搜索，这枚是「挨着看」的浏览式入口。 */
.hx-sw-wrap { position: relative; display: none; flex: none; }
body.hx-tool .hx-sw-wrap { display: block; }
.hx-sw {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 2px;
  color: var(--hx-dim);
  cursor: pointer;
  transition: color 0.22s var(--hx-ease), border-color 0.22s var(--hx-ease), background-color 0.35s var(--hx-ease);
}
.hx-sw:hover, .hx-sw[aria-expanded="true"] { color: var(--hx-acc); }
.hx-sw svg { width: var(--hx-t15); height: var(--hx-t15); }
.hx-sw:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: 2px; }

/* 大弹窗：实底 + 细线框，和导航同一套语言；遮罩压暗 + 轻糊（导航本身已用 blur） */
.hx-sw-mask {
  position: fixed; inset: 0; z-index: var(--hx-z-dlg);
  display: flex; align-items: flex-start; justify-content: center;
  padding: calc(var(--hx-nav-h) + clamp(16px, 4vh, 48px)) clamp(14px, 4vw, 40px) clamp(16px, 4vh, 40px);
  background: var(--hx-mask);
  -webkit-backdrop-filter: blur(var(--hx-mask-blur));
          backdrop-filter: blur(var(--hx-mask-blur));
}
.hx-sw-mask[hidden] { display: none; }
.hx-sw-modal {
  display: flex; flex-direction: column;
  width: min(1060px, 100%);
  max-height: 100%;
  background: var(--hx-dlg-bg);
  border: 1px solid var(--hx-dlg-line);
  border-radius: var(--hx-dlg-radius);
}
.hx-sw-mhead {
  display: flex; align-items: center; gap: 16px; flex: none;
  padding: clamp(14px, 2vw, 20px) clamp(16px, 2.4vw, 26px);
  border-bottom: 1px solid var(--hx-line);
}
.hx-sw-mt {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  font-size: clamp(17px, 2.2vw, 22px); font-size: round(clamp(17px, 2.2vw, 22px), 1px); font-weight: 800; letter-spacing: -0.02em;
  color: var(--hx-ink);
}
.hx-sw-mt span {
  font-family: var(--hx-mono); font-size: var(--hx-t9-5); font-weight: 400;
  letter-spacing: 0.2em; color: var(--hx-dim2);
}
.hx-sw-mt span b { font-weight: 400; color: var(--hx-acc); }
.hx-sw-mx {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; flex: none;
  background: transparent; border: 1px solid var(--hx-dlg-line); border-radius: var(--r-btn);
  color: var(--hx-dim); cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}
.hx-sw-mx:hover { border-color: var(--hx-acc); color: var(--hx-acc); }
.hx-sw-mx svg { width: var(--hx-t14); height: var(--hx-t14); }
.hx-sw-mx:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: 2px; }

/* 弹窗主体：分类块平铺，窄了自动收列 */
.hx-sw-mbody {
  overflow-y: auto; overscroll-behavior: contain;
  padding: clamp(14px, 2vw, 24px) clamp(16px, 2.4vw, 26px) clamp(18px, 2.4vw, 28px);
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(228px, 1fr));
  gap: clamp(16px, 2.2vw, 26px) clamp(16px, 2.4vw, 30px);
  align-items: start;
}
.hx-sw-g { min-width: 0; }
.hx-sw-gh {
  display: flex; align-items: center; gap: 9px;
  padding-bottom: 9px; margin-bottom: 2px;
  border-bottom: 1px solid var(--hx-line);
  font-size: var(--hx-t13); font-weight: 700; letter-spacing: 0.01em;
  color: var(--hx-ink);
}
.hx-sw-gh i {
  font-family: var(--hx-mono); font-style: normal;
  font-size: var(--hx-t9-5); letter-spacing: 0.16em;
  color: var(--hx-acc);
  border: 1px solid var(--hx-acc);
  padding: 3px 5px 2px; line-height: 1;
}
.hx-sw-gh b {
  margin-left: auto;
  font-family: var(--hx-mono); font-weight: 400;
  font-size: var(--hx-t9); letter-spacing: 0.16em; color: var(--hx-dim2);
}
/* 条目：单行「名称 … 状态」，和首页索引行同一套反色语言；
   一句话描述不放正文（会显满显吵），收进 title 悬停提示 */
.hx-sw-i {
  -webkit-appearance: none; appearance: none;
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 8px 10px;
  background: transparent; border: 1px solid transparent; border-radius: 2px;
  color: var(--hx-dim);
  font: inherit; font-size: var(--hx-t13); text-align: left;
  cursor: pointer;
  transition: background 0.14s linear, color 0.14s linear, border-color 0.14s linear;
}
.hx-sw-i span { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hx-sw-i em {
  flex: none;
  font-family: var(--hx-mono); font-style: normal;
  font-size: var(--hx-t8-5); letter-spacing: 0.14em; color: var(--hx-dim2);
}
/* hover 整条反色：薄荷底 + 近黑字，和索引行同一套主交互语言 */
.hx-sw-i:hover { background: var(--hx-inv-bg); color: var(--hx-inv-ink); border-color: var(--hx-inv-bg); }
.hx-sw-i:hover em { color: var(--hx-inv-dim); }
/* 当前工具：薄荷描边 + 薄荷字，不反色（反色留给 hover） */
.hx-sw-i.is-on { color: var(--hx-acc); border-color: var(--hx-acc); }
.hx-sw-i.is-on em { color: var(--hx-acc); opacity: 0.7; }
/* 个人模块条目：薄荷「个人」小标（只有管理员看得到这枚） */
.hx-sw-i em.is-p { color: var(--hx-acc); }
.hx-sw-i:hover em.is-p { color: var(--hx-inv-dim); }
.hx-sw-i:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: -1px; }

/* ============================================================
   工具排序弹窗（设置面板 →「工具排序」入口）
   比「全部功能」小一号；标题 / 关闭键 / 进出动画全部复用 sw 那套语言。
   只决定「分类内部的行序」，分类段顺序不变。
   ============================================================ */
.hx-sort-mask {
  position: fixed; inset: 0; z-index: var(--hx-z-dlg);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(14px, 4vw, 40px);
  background: var(--hx-mask);
  -webkit-backdrop-filter: blur(var(--hx-mask-blur));
          backdrop-filter: blur(var(--hx-mask-blur));
}
.hx-sort-mask[hidden] { display: none; }
.hx-sort-mask:not([hidden]) { animation: hxFade 0.18s var(--hx-ease) both; }
.hx-sort-mask:not([hidden]) .hx-sort-modal { animation: hxPopIn 0.34s var(--hx-spring) both; }
.hx-sort-mask.is-out { animation: hxMaskOut 0.15s var(--hx-ease) both; }
.hx-sort-mask.is-out .hx-sort-modal { animation: hxPopOut 0.15s var(--hx-ease) both; }

.hx-sort-modal {
  display: flex; flex-direction: column;
  width: min(520px, 100%);
  max-height: 100%;
  background: var(--hx-dlg-bg);
  border: 1px solid var(--hx-dlg-line);
  border-radius: var(--hx-dlg-radius);
}
.hx-sort-body {
  overflow-y: auto; overscroll-behavior: contain;
  padding: 4px clamp(16px, 2.4vw, 24px) clamp(14px, 2.2vw, 20px);
}

/* 单选项：整行可点，左圆点 + 名称 + 一句说明 */
.hx-sort-o {
  -webkit-appearance: none; appearance: none;
  display: flex; align-items: flex-start; gap: 12px; width: 100%;
  padding: 14px 2px; background: transparent; border: 0;
  border-bottom: 1px solid var(--hx-line);
  font: inherit; text-align: left; cursor: pointer;
  color: var(--hx-dim);
  transition: color 0.16s var(--hx-ease);
}
.hx-sort-o:last-child { border-bottom: 0; }
.hx-sort-o:hover { color: var(--hx-ink); }
.hx-sort-o:focus-visible { outline: 1px solid var(--hx-acc); outline-offset: -1px; }
.hx-sort-o .hx-sort-dot {
  flex: none; width: 15px; height: 15px; margin-top: 1px;
  border: 1px solid var(--hx-line-2); border-radius: 50%;
  display: grid; place-items: center;
  transition: border-color 0.16s var(--hx-ease);
}
.hx-sort-o .hx-sort-dot::after {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: var(--hx-acc); transform: scale(0.2); opacity: 0;
  transition: transform 0.16s var(--hx-ease), opacity 0.16s var(--hx-ease);
}
.hx-sort-o.is-on { color: var(--hx-ink); }
.hx-sort-o.is-on .hx-sort-dot { border-color: var(--hx-acc); }
.hx-sort-o.is-on .hx-sort-dot::after { transform: scale(1); opacity: 1; }
.hx-sort-o .hx-sort-txt { min-width: 0; }
.hx-sort-o .hx-sort-t { display: block; font-size: var(--hx-t13-5); font-weight: 700; color: inherit; letter-spacing: 0.01em; }
.hx-sort-o .hx-sort-d2 { display: block; margin-top: 4px; font-size: var(--hx-t11-5); line-height: 1.5; color: var(--hx-dim2); }
.hx-sort-o.is-on .hx-sort-d2 { color: var(--hx-dim); }

@media (max-width: 560px) {
  .hx-sort-mask { align-items: flex-end; padding: 0; }
  .hx-sort-modal { width: 100%; border-left: 0; border-right: 0; border-bottom: 0; }
}
/* 焦点程序化落在弹窗本体上，不要可见外框（内部按钮各自有 focus-visible） */
.hx-sort-modal:focus, .hx-sort-modal:focus-visible { outline: none; }

/* ============================================================
   12. 工具视图格栅化（换皮方向 B：整套换皮）
   ------------------------------------------------------------
   参考站 DNA 的招牌是「无阴影细线格栅板」：gap:0 + 1px 内线，格子之间
   共享边框，而不是各自一圈独立卡片线。首页的索引行 / 六宫格 / 统计带
   已经是这个语言；本章把工具视图里最后的「独立卡片」表面收编进来：
   · 图标网格 / 项目库：gap 归零、共享发丝内线、圆角归零
   · hover / 选中改走底色与内嵌环——共享发丝线不改色（改色格栅会花），
     内嵌环不占布局、不传染邻居（旧作法是 1px 外描边，格栅下会压到隔壁）
   · 选中色 --ic-sel：旧像素工坊暖赭石 #a6663d → --hx-acc（亮暗各一套）
   · 分类头并作格栅跨列行：发丝线 + 薄荷小方块（旧作法是 22px/8px 外边距
     断组；2026-10-22「二十多条横线割裂」的顾虑，在整套换皮下让位于
     参考站的连续格栅语言——割裂感由小方块和留白重新承担）
   · 小件圆角收 2px（快捷钮 / 来源角标 / 首字块 / 胶囊 / 徽章 / 筛选 chip），
     与本章 1191 行附近 .badge 的既有口径一致
   · 投影：--shadow-1/2 已在两个主题块置空（40+ 处一处收尽）；本章补
     icons.css 里两处写死的 0 10px 30px 弹层影
   ============================================================ */

/* ---- 选中色收编：暖赭石 → 薄荷（--ic-sel 还管来源过滤钮的 some 态）---- */
html[data-skin="helix"] #view-icons { --ic-sel: var(--hx-acc); }

/* ---- 图标网格：独立卡片 → 细线格栅板 ---- */
#legacy-app #view-icons .ic-grid {
  gap: 0;
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}
#legacy-app #view-icons .ic-card {
  border-radius: 0;
  border-top: 0; border-left: 0;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
/* hover 只染底色：共享发丝线保持统一（改 border-color 会让格栅花掉）；
   用 --hx-field-bg 而非 --icon-bg——后者在暗色下比格栅底还亮，会翻出格子 */
#legacy-app #view-icons .ic-card:hover {
  border-color: var(--border);
  background: var(--hx-field-bg);
}
/* 选中：薄荷淡底 + 2px 内嵌环（写在 hover 之后，选中态压过 hover） */
#legacy-app #view-icons .ic-card.is-sel {
  border-color: var(--border);
  background: var(--accent-soft-bg);
  box-shadow: inset 0 0 0 2px var(--hx-acc);
}
#legacy-app #view-icons .ic-card.is-sel .ic-card-cn { color: var(--text); }
/* 分类头：并作格栅的跨列行 */
#legacy-app #view-icons .ic-cat-head {
  margin: 0; padding: 13px 12px 11px;
  border-bottom: 1px solid var(--border);
}
#legacy-app #view-icons .ic-cat-head::before {
  content: ""; flex: none; width: 6px; height: 6px;
  background: var(--hx-acc);
}
#legacy-app #view-icons .ic-cat-head-t { letter-spacing: 0.3px; }
/* 卡片内小件圆角收方 */
#legacy-app #view-icons .ic-card-more { border-radius: 2px; }
#legacy-app #view-icons .ic-card-src { border-radius: 2px; }

/* ---- 项目库：独立卡 → 发丝网格（首页索引行同款语言）---- */
#legacy-app #view-icons .ic-plist {
  gap: 0;
  border-top: 1px solid var(--border);
  border-left: 1px solid var(--border);
}
#legacy-app #view-icons .ic-pcard {
  border-radius: 0;
  border-top: 0; border-left: 0;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
#legacy-app #view-icons .ic-pcard:hover {
  border-color: var(--border);
  background: var(--hx-field-bg);
}
/* 首字色块 / 枚数胶囊 / 徽章 / 筛选 chip：圆角收 2px（helix 方形语言） */
#legacy-app #view-icons .ic-pcard-mono { border-radius: 2px; }
#legacy-app #view-icons .ic-pcard-count { border-radius: 2px; }
#legacy-app #view-icons .ic-pbadge { border-radius: 2px; }
#legacy-app #view-icons .ic-lib-mine { border-radius: 2px; }

/* ---- 弹层写死的投影清零（--shadow-* 已置空，这两处是硬编码值）---- */
#legacy-app #view-icons .ic-src-pop,
#legacy-app #view-icons .ic-card-pop { box-shadow: none; }

/* ---- 输入聚焦：撤 3px 扩散环，只留边框换色（helix 输入框惯例）---- */
#legacy-app #view-icons .ic-ip-url:focus,
#legacy-app #view-spec .ic-q:focus { box-shadow: none; }

/* ---- 按钮 focus-visible：旧双环（surface + text-3）→ helix 单线 outline ---- */
#legacy-app #view-icons .ic-tip:focus-visible,
#legacy-app #view-icons .ic-ip-x:focus-visible,
#legacy-app #view-icons .ic-ip-seg .ic-seg-b:focus-visible {
  outline: 1px solid var(--hx-acc);
  outline-offset: -1px;
  box-shadow: none;
}
