/* ==========================================================================
   资源下载门户 —— 前台样式
   风格：清爽、克制、无广告位；主色青玉绿
   ========================================================================== */

:root {
  --primary: #0e7c66;
  --primary-dark: #0a5f4e;
  --primary-soft: #e8f4f1;
  --primary-line: #cfe6e0;

  --text: #1b2733;
  --text-2: #5b6b7c;
  --text-3: #64748b;
  /* ⚠️ 对比度规则（2026-10-11 实测）：--text-3 在**纯白底**上才是 4.76:1，
     任何浅色底都会把它压到 WCAG AA 的 4.5:1 以下 ——
       灰底 --bg #f5f7f7 → 4.43 ｜ --border-2 #eef1f2 → 4.19 ｜ 主题色淡底 #d5e6e3 → 3.68。
     所以：**凡是落在非纯白底上的次要文字，一律用 --text-2 或更深**。
     例外：.hot-tag-cnt 坐在主题色淡底上，用 --primary-dark 与标签名同色系。
     新增样式时请照此办理，别再往彩色底上放 --text-3。 */

  --bg: #f5f7f7;
  --card: #ffffff;
  --border: #e6eaec;
  --border-2: #eef1f2;

  --radius: 10px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(16, 40, 34, .04);
  --shadow-hover: 0 6px 20px rgba(16, 40, 34, .08);

  --maxw: 1200px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", sans-serif;
  /* 字阶（2026-10-12 归并） */
  --fs-2xs: 11px;  /* 10 / 10.5 / 11 */
  --fs-xs: 12px;  /* 11.5 / 12 / 12.5 */
  --fs-sm: 13px;  /* 13 */
  --fs-base: 14px;  /* 13.5 / 14 / 14.5 */
  --fs-md: 16px;  /* 15 / 15.5 / 16 / 16.5 —— input/select/textarea 固定 16（iOS 聚焦防缩放） */
  --fs-lg: 18px;  /* 17 / 18 */
  --fs-xl: 20px;  /* 19 / 20 / 21 */
  --fs-2xl: 24px;  /* 22 / 23 / 24 / 25 / 26 */
  --fs-3xl: 32px;  /* 30 / 32 */
  --fs-display: 40px;  /* 38 / 40 / 42 / 46 */
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font);
  font-size: var(--fs-base);
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
a:hover { color: var(--primary); }

img { max-width: 100%; display: block; }

button, input, select, textarea { font-family: inherit; font-size: inherit; }

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 20px;
}

/* ------------------------------ 顶部导航 ------------------------------ */

.site-header {
  background: #fff;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  z-index: 100;
}

.header-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 28px;
  padding: 12px 0 10px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-xl);
  font-weight: 700;
  letter-spacing: .5px;
  color: var(--text);
  /* flex-shrink 必须是 1：顶栏第一行只有 logo 和「登录/注册（或头像+后台+退出）」两块，
     站点名很长时如果 logo 不可压缩，就会把操作区挤到下一行、导航再被顶到第三行。
     允许压缩后，logo-text 走省略号，操作区始终留在第一行。 */
  flex-shrink: 1;
  /* 顶栏两行布局（全宽度统一）：第 1 行 = logo + 登录/注册，第 2 行 = 导航。
     换行型 flex 容器的视觉顺序 = order 后的文档顺序，所以靠 order 把
     导航（order:3）推到第 2 行，logo/操作区留在第 1 行。
     注意：不要靠调整 DOM 顺序实现，order 更小改动、且不碰 navCategories 渲染逻辑。 */
  order: 1;
  min-width: 0;
}

/* logo 文字过长时截断，避免窄屏把「登录/注册」挤出屏幕 */
.logo-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.logo:hover { color: var(--primary); }

/* 后台可上传自定义 logo 图片，未上传时回退到首字母方块 */
.logo-img {
  height: 34px;
  width: auto;
  max-width: 190px;
  object-fit: contain;
  flex-shrink: 0;
  display: block;
}

.logo-mark {
  width: 34px;
  height: 34px;
  border-radius: 9px;
  background: var(--primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-lg);
  font-weight: 700;
  flex-shrink: 0;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  /* 导航栏配色（2026-10-09，后台「导航栏管理」可配）。
     ⚠️ 每个 var() 都必须带兜底值 —— 设置留空时 head.ejs 根本不输出这个变量，
        不带兜底会解析成无效值、属性退化成 unset（导航整块变色/透明）。 */
  background: var(--nav-bg, transparent);
  color: var(--nav-fg, var(--text-2));
  /* 第 2 行：basis 100% → 整块独占一行，无论屏幕多宽都不会挤到 logo 那行。
     （早先用 flex:1 1 0%，基准宽度为 0 → 永不换行，末尾栏目会被裁掉。） */
  order: 3;
  flex: 1 1 100%;
  width: 100%;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  /* 右缘渐隐：导航放不下时可横滑，用渐隐提示「右边还有栏目」，
     否则末尾栏目看起来像被截断。纯视觉，不改布局与滚动行为。 */
  -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
  mask-image: linear-gradient(to right, #000 calc(100% - 26px), transparent 100%);
}
.main-nav::-webkit-scrollbar { display: none; }

/* 只有真的配了背景色才加内边距 —— 否则文字会贴着色块边缘。
   没配背景色时这个类不生效，导航与改动前逐像素一致。 */
.main-nav.has-bg {
  padding: 6px 10px;
  border-radius: var(--radius-sm);
}

.main-nav a {
  padding: 7px 13px;
  border-radius: var(--radius-sm);
  color: var(--nav-fg, var(--text-2));
  white-space: nowrap;
  font-size: var(--fs-base);
  transition: background .15s, color .15s;
}

.main-nav a:hover { background: var(--nav-hover-bg, var(--primary-soft)); color: var(--nav-active-fg, var(--primary)); }
.main-nav a.active { color: var(--nav-active-fg, var(--primary)); font-weight: 600; background: var(--nav-hover-bg, var(--primary-soft)); }

/* 顶部搜索框：与 hero-search 同源（圆角 + 主色 focus 描边） */
.header-search {
  position: relative;
  flex: 1 1 280px;
  max-width: 420px;
  min-width: 180px;
  order: 2;
  /* 2026-10-07「搜索框右移」：用 auto 外边距吃掉 logo 与搜索框之间的空余，
     让搜索框紧贴右侧的登录/注册区（更符合常见站点习惯）。
     空余只在宽屏出现 —— 窄屏时搜索框会长满可用宽度，auto 外边距拿不到空间，
     所以 ≤860px 那一档把外边距还给 .header-actions（见文件末尾的响应式段）。 */
  margin-left: auto;
  display: flex;
  align-items: center;
}
/* 原先框内左侧那个装饰放大镜已删除（2026-10-07）：
   搜索动作由右侧圆形按钮承担，一左一右两个放大镜反而让人分不清哪个能点。 */
.header-search input {
  flex: 1;
  height: 36px;
  /* 左侧内边距由 34px 收到 16px：前导放大镜已去掉（2026-10-07） */
  padding: 0 38px 0 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  font-size: var(--fs-base);
  color: var(--text);
  outline: none;
  transition: border-color .15s, box-shadow .15s, background .15s;
}
.header-search input::placeholder { color: var(--text-3); }
.header-search input:hover { border-color: #c4d1da; }
.header-search input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(14, 124, 102, .12);
  background: #fff;
}
.header-search button[type="submit"] {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 28px;
  height: 28px;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background .15s;
}
.header-search button[type="submit"]:hover { background: var(--primary-dark); }

/* 搜索下拉：定位在表单内 input 下方，宽度与 input 同步 */
.header-search-dd {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 36px; /* 留出右侧提交按钮宽度 */
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0,0,0,.10);
  padding: 6px 0;
  z-index: 100;
  max-height: 460px;
  overflow-y: auto;
}
.header-search { position: relative; }
.hs-block { padding: 4px 0; }
.hs-block + .hs-block { border-top: 1px solid var(--border-2); }
.hs-title {
  font-size: var(--fs-xs);
  color: var(--text-3);
  padding: 6px 14px 4px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-weight: 600;
  letter-spacing: 0.3px;
}
.hs-clear {
  background: none;
  border: 0;
  color: var(--text-3);
  font-size: var(--fs-xs);
  cursor: pointer;
  padding: 0;
}
.hs-clear:hover { color: var(--primary); }
.hs-item, .hs-item-link {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 14px;
  border: 0;
  background: none;
  text-align: left;
  color: var(--text);
  font-size: var(--fs-base);
  text-decoration: none;
  cursor: pointer;
  transition: background .12s;
}
.hs-item:hover, .hs-item-link:hover,
.hs-item.is-active, .hs-item-link.is-active { background: var(--primary-soft); color: var(--primary); }
.hs-item .hs-ic, .hs-item-link .hs-ic { color: var(--text-3); flex-shrink: 0; }
.hs-item:hover .hs-ic, .hs-item-link:hover .hs-ic,
.hs-item.is-active .hs-ic, .hs-item-link.is-active .hs-ic { color: var(--primary); }
.hs-text {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hs-meta {
  font-size: var(--fs-xs);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

/* 导航末尾小箭头：右缘渐隐的视觉锚点 */
.nav-end-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;  height: 22px;
  border-radius: 6px;
  background: var(--primary-soft);
  color: var(--primary);
  font-size: var(--fs-base);
  font-weight: 700;
  margin-left: 4px;
  flex-shrink: 0;
}

/* ⚠️ 2026-10-05 起导航栏已取消「更多 ▾」（栏目全部平铺）。
   以下 .nav-more / .nav-more-arrow / .nav-more-panel 规则当前无任何引用，
   保留仅为回滚方便 —— 新代码不要再依赖它们。 */
.nav-more { position: relative; }
.nav-more summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 7px 13px;
  border-radius: var(--radius-sm);
  color: var(--text-2);
  white-space: nowrap;
  font-size: var(--fs-base);
  user-select: none;
}
.nav-more summary::-webkit-details-marker { display: none; }
.nav-more summary:hover { background: var(--primary-soft); color: var(--primary); }
.nav-more[open] summary { background: var(--primary-soft); color: var(--primary); }
.nav-more-arrow {
  width: 0; height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  margin-left: 2px;
  transition: transform .15s;
}
.nav-more[open] .nav-more-arrow { transform: rotate(180deg); }
.nav-more-panel {
  display: none;
  position: absolute;
  top: 100%; right: 0;
  margin-top: 6px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-hover);
  padding: 6px;
  min-width: 140px;
  z-index: 110;
}
.nav-more[open] .nav-more-panel { display: flex; flex-direction: column; gap: 2px; }
.nav-more-panel a {
  padding: 7px 12px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  color: var(--text-2);
}
.nav-more-panel a:hover { background: var(--primary-soft); color: var(--primary); }
.nav-more-panel a.active { color: var(--primary); background: var(--primary-soft); font-weight: 600; }

@media (min-width: 861px) {
  /* 宽屏下「更多」与普通链接齐平，不出抽屉 —— 但保留 dropdown 给 ≥861px 的二级入口 */
  .nav-more summary { /* 与 .main-nav a 视觉一致 */ }
  .nav-more[open] .nav-more-panel { display: flex; }
}
@media (max-width: 860px) {
  /* 窄屏：不横滑，改为换行平铺。
     ⚠️ flex-wrap: wrap 是必须的。基础规则里 .main-nav 是 overflow-x:auto + nowrap，
     这里又把 overflow 改成 visible —— 而 nowrap 的 flex 子项（个个 white-space:nowrap）
     不会收缩，会直接顶出容器、把整页撑出横向滚动条。
     实测（2026-10-05 改前）：640px 下导航内容 744px / 容器 600px，
     390px 下 744px / 362px，两种宽度都触发了整页横向滚动。 */
  .main-nav { overflow-x: visible; flex-wrap: wrap; row-gap: 4px; mask-image: none; -webkit-mask-image: none; }
}

.header-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 10px;
  /* 第 1 行右侧：与 logo 同一行，靠 margin-left:auto 顶到最右。
     flex:0 0 auto → 按内容宽度，不被压缩。 */
  order: 2;
  flex: 0 0 auto;
  /* margin-left:auto 已挪到 .header-search 上（2026-10-07）：两处都写会把空余
     对半分，搜索框就贴不到操作区旁边了。窄屏在 @media ≤860px 里再还给这里。 */
  min-height: 34px;
}

/* ══════════ mobileux-20261008 手机版页头重排（方案 S4）══════════
   目标：窄屏第 1 行 = LOGO 图标 + LOGO 文字 + 登录/注册，第 2 行 = 搜索框 + 汉堡。
   改前实测（390px）：.logo-text 宽 0px（需要 135px）—— 站名被搜索框挤没了。
   ⚠️ .header-toolrow 的桌面属性必须与原来的 .header-search 完全等价
      （flex:1 1 280px / max-width:420px / min-width:180px / order:2 / margin-left:auto），
      否则桌面端搜索框的宽度或位置会变。
   ⚠️ 所有重排必须包在 @media (max-width:860px) 内 —— 实测不包时桌面 1280px 下
      搜索框会被 flex:1 1 100% 拉成 1160px 整行、页头 103px → 143px。 */
.header-toolrow {
  display: flex;
  align-items: center;
  flex: 1 1 280px;
  max-width: 420px;
  min-width: 180px;
  order: 2;
  margin-left: auto;
}
/* ⚠️ .header-search 自带的 order:2 现在只作用于 .header-toolrow **内部**
   （里面只有搜索框和汉堡两个子项）。不显式写成 1 的话，汉堡（order 默认 0）
   会排到搜索框左边 —— 手机上就是「汉堡在左、搜索框在右」，不符合习惯。 */
.header-toolrow .header-search {
  order: 1;
  flex: 1 1 auto;
  max-width: none;
  min-width: 0;
  margin-left: 0;
}
.header-toolrow .nav-toggle { order: 2; }

/* ⚠️ 861–1024px 这一档**不要**给 .header-toolrow 加 margin-left:0。
   原来 .header-search 的 margin-left:auto（基础规则）在 ≤860 块里才被改成 0，
   861–1024 区间一直是 auto —— 实测改前 1024px 下搜索框 x=438（顶右）。
   一开始我误以为 1024 断点里也改了，加了一条 @media (max-width:1024px) 覆盖，
   结果把搜索框拉回左边、整体左移 170px（1024 guest: x438 → x267.5，实测抓到）。
   现在不再加这一档，861–1024 与改前逐项一致。 */

/* 窄屏重排：工具行独占一行（第 2 行），操作区顶到第 1 行右侧。 */
@media (max-width: 860px) {
  .header-toolrow {
    flex: 1 1 100%;
    max-width: none;
    min-width: 0;
    order: 3;
    margin-left: 0;
    gap: 8px;
  }
  .header-actions { order: 2; margin-left: auto; }
  .main-nav { order: 4; }
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 38px;
  padding: 0 18px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: var(--primary);
  color: #fff;
  cursor: pointer;
  white-space: nowrap;
  font-size: var(--fs-base);
  transition: all .16s;
}

.btn:hover { background: var(--primary-dark); color: #fff; }

.btn-ghost {
  background: #fff;
  border-color: var(--border);
  color: var(--text-2);
}
.btn-ghost:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }

.btn-sm { height: 32px; padding: 0 13px; font-size: var(--fs-sm); }
.btn-lg { height: 44px; padding: 0 26px; font-size: var(--fs-md); }
.btn-block { width: 100%; }

/* ⚠️ 长文案按钮（「扫码支付 ¥X 立即下载」）：窄屏允许折行。
   .btn 默认是 white-space:nowrap + 固定 height，文字**不会**折行；
   而 .dl-gate 卡片在 320~360px 的手机上内容区只有 168~208px，
   这个按钮要 229px → 直接把卡片撑破（2026-10-14 实测：360px 溢出 21px、320px 溢出 61px）。
   ⚠️ 注意：光挂 .btn-wrap 只能治 360px 及以上；320px 还必须配合
      @media (max-width:640px) 里的 .dl-gate-main{min-width:0}（否则卡片仍被撑破 32px）。
   短文案按钮不受影响（宽容器里宽度够，不会折行）。
   ⚠️ flex-wrap:wrap 是给 .btn-l2 用的（见下面「立即下载」换行的注释）——
      .btn 是 inline-flex，不加 wrap 的话里面的 span 永远换不到第二行。 */
.btn-wrap {
  white-space: normal;
  height: auto;
  min-height: 44px;
  padding: 9px 20px;
  line-height: 1.32;
  text-align: center;
  flex-wrap: wrap;
}

.user-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px 5px 5px;
  border: 1px solid var(--border);
  border-radius: 20px;
  background: #fff;
}
.user-chip:hover { border-color: var(--primary-line); background: var(--primary-soft); }

.user-avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  font-weight: 600;
  flex-shrink: 0;
}

.user-chip .u-text {
  display: flex;
  flex-direction: column;
  line-height: 1.25;
  min-width: 0;
}

.user-chip .u-name { font-size: var(--fs-base); font-weight: 500; white-space: nowrap; }
.user-chip .u-points { font-size: var(--fs-xs); color: var(--text-3); white-space: nowrap; }

/* ------------------------------ 页面容器 ------------------------------ */

.page { padding: 24px 0 56px; }

.notice-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 1px solid var(--primary-line);
  border-left: 3px solid var(--primary);
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  margin-bottom: 12px;
  font-size: var(--fs-base);
  color: var(--text-2);
}
.notice-bar .tag {
  color: var(--primary);
  font-weight: 600;
  flex-shrink: 0;
}

/* ------------------------------ 首页公告区（可后台开关） ------------------------------ */
/* 通知条（settings.announcement）始终置顶；公告列表作为「更多公告」二级折叠入口，
   避免与通知条视觉重复又便于深读历史公告。 */

.announce-toggle {
  margin-bottom: 20px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.announce-toggle > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  font-size: var(--fs-sm);
  color: var(--text-2);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background .15s;
}
.announce-toggle > summary::-webkit-details-marker { display: none; }
.announce-toggle > summary:hover { background: var(--primary-soft); color: var(--primary); }
.announce-toggle[open] > summary { color: var(--primary); background: var(--primary-soft); }
.announce-toggle .an-toggle-icon { font-size: var(--fs-base); }

.announce-toggle .announce-list {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--border);
  padding: 6px 0;
}

.announce-item {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.announce-item > summary {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  cursor: pointer;
  list-style: none;
  transition: background .15s;
}
.announce-item > summary::-webkit-details-marker { display: none; }
.announce-item > summary:hover { background: var(--primary-soft); }

.announce-item .an-title {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--text);
}

.announce-item .an-date {
  flex-shrink: 0;
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.announce-item .an-arrow {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--text-3);
  border-bottom: 2px solid var(--text-3);
  transform: rotate(45deg) translateY(-2px);
  transition: transform .2s;
}
.announce-item[open] .an-arrow { transform: rotate(-135deg) translateY(-2px); }

.announce-item .an-body {
  padding: 12px 16px 16px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-base);
  color: var(--text-2);
}

/* ------------------------------ Hero ------------------------------ */

.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse at top right, rgba(14, 124, 102, .10), transparent 60%),
    radial-gradient(ellipse at bottom left,  rgba(14, 124, 102, .06), transparent 55%),
    #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0;
  margin-bottom: 24px;
}

/* 浅色网格底纹 + 顶部 mask 渐隐，做装饰不抢戏 */
.hero-bg {
  position: absolute; inset: 0;
  background-image:
    linear-gradient(to right,  rgba(14,124,102,.04) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(14,124,102,.04) 1px, transparent 1px);
  background-size: 32px 32px;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
          mask-image: linear-gradient(to bottom, #000 0%, transparent 78%);
  pointer-events: none;
}

.hero-inner {
  position: relative;
  padding: 30px 40px 22px;
  text-align: center;
}

.hero-title {
  margin: 0 0 4px;
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: .3px;
  color: var(--text);
}
.hero-subtitle {
  margin: 0 0 16px;
  color: var(--text-2);
  font-size: var(--fs-sm);
}

/* 搜索区：2026-10-07 改 —— 去掉框内左侧的装饰放大镜；原来的文字按钮
   挪进输入框右侧、变成圆形放大镜。所以这里从 flex 改成
   「输入框占满 + 按钮绝对定位在框内右侧」。 */
.hero-search {
  position: relative;
  max-width: 560px;
  margin: 0 auto 14px;
  display: block;
}

.hero-search input {
  width: 100%;
  height: 44px;
  /* 右侧留 54px 给框内的圆形按钮，免得长关键字被按钮压住 */
  padding: 0 54px 0 20px;
  border: 1px solid var(--border);
  border-radius: 999px;
  outline: none;
  background: #fff;
  font-size: var(--fs-base);
  color: var(--text);
  box-shadow: var(--shadow);
  transition: border-color .15s, box-shadow .15s;
}
.hero-search input::placeholder { color: var(--text-3); }
.hero-search input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(14, 124, 102, .12);
}

/* 搜索按钮：嵌在输入框右侧的圆形放大镜。
   是 type="submit"，所以点它和按回车都会提交，不需要额外 JS。 */
.hero-search-btn {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: #fff;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: filter .15s;
}
.hero-search-btn:hover { filter: brightness(1.08); }
.hero-search-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* 热门搜索关键字：搜索框下方、统计数字上方一行。
   每个词是一个真超链接，默认黑色（--text），颜色可由后台「热门关键字」逐条设置。
   hover 时加下划线 + 浅色底，并跟随站内其它链接转主题色（行内 style 优先级更高，
   所以设过颜色的关键字 hover 不变色，靠下划线/底色提示可点）。
   宽度与 .hero-search 对齐（560px），窄屏自动换行。 */
.hero-hot {
  max-width: 560px;
  margin: 0 auto 14px;
  font-size: var(--fs-xs);
  line-height: 1.9;
  color: var(--text-3);
}
.hero-hot-label { color: var(--text-3); }
.hero-hot-word {
  /* 默认黑色（--text = 本站正文色 #1b2733，视觉上就是黑）。
     后台给某个关键字单独设了颜色时，模板会输出行内 style="color:…" 覆盖这里。
     hover 仍然加下划线 —— 否则黑色文字看不出是可点的链接。 */
  color: var(--text);
  /* 左右各半个汉字宽（em 随字号缩放）→ 相邻两个词之间正好空出**一个汉字**。
     2026-10-14 杨哥要求。原来是 4px 10px（左右各 10px），
     再加上模板里那个「·」分隔符，两词之间实到 ~29px（≈2.4 个汉字），太散。
     现在模板不再输出分隔符，间距只由这里决定 —— 改这个值就能整体调松紧。 */
  padding: 4px 0.5em;
  border-radius: 4px;
  transition: background .15s;
}
.hero-hot-word:hover { background: var(--primary-soft); text-decoration: underline; }
/* .hero-hot-sep（词间「·」分隔符）2026-10-14 随模板一起废弃 —— 保留此注记，
   免得以后有人看到 index.ejs 里没有分隔符又来加。 */

.hero-stats {
  display: flex;
  justify-content: center;
  align-items: baseline;
  gap: 0;
  color: var(--text-3);
  font-size: var(--fs-xs);
}
.hero-stat {
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
  padding: 0 14px;
  position: relative;
}
.hero-stat + .hero-stat::before {
  content: '';
  position: absolute;
  left: 0; top: 50%;
  transform: translateY(-50%);
  width: 1px; height: 10px;
  background: var(--border);
}
.hero-stat-num {
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--text-2);
  font-variant-numeric: tabular-nums;
}
.hero-stat-label { color: var(--text-3); }

/* 搜索页标题下方那行小字：多关键字时提示「同时包含：A、B」 */
.desc-note { color: var(--text-3); font-size: var(--fs-xs); }

/* 窄屏：标题缩小、stats 收紧 */


/* ------------------------------ 版块 ------------------------------ */

.section-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}
/* 标签分类 / 资料属性 / 下载积分 / 资源大小：这几个版块现在也能被拖到栏目之间，
   所以进了栅格。它们要保持整行宽度，显式跨两列。
   （改造前它们在栅格外面，靠 style="margin-top:18px" 拉开距离。） */
.section--wide { grid-column: 1 / -1; }

.section {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
}

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 15px 20px;
  border-bottom: 1px solid var(--border-2);
}

.section-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--fs-md);
  font-weight: 600;
  margin: 0;
}

.section-title::before {
  content: '';
  width: 3px;
  height: 15px;
  border-radius: 2px;
  background: var(--primary);
  flex-shrink: 0;
}

.section-more {
  font-size: var(--fs-sm);
  color: var(--text-3);
  display: flex;
  align-items: center;
  gap: 3px;
}
.section-more:hover { color: var(--primary); }

/* ---- Tab 轮换框（推荐下载 / 下载最多 / 最新下载） ---- */

/* 占满整行 */
.tab-section { grid-column: 1 / -1; }

.tab-section .section-head {
  padding: 8px 16px 0;
  align-items: flex-end;
}

.tab-nav {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  min-width: 0;
}

.tab-btn {
  position: relative;
  padding: 9px 14px 12px;
  border: 0;
  background: transparent;
  color: var(--text-2);
  font-family: inherit;
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  border-radius: 6px 6px 0 0;
  transition: color .16s, background .16s;
}

.tab-btn:hover { color: var(--primary); background: var(--primary-soft); }
.tab-btn.active { color: var(--primary); }

.tab-btn.active::after {
  content: '';
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 0;
  height: 2px;
  border-radius: 2px;
  background: var(--primary);
}

/* 轮动框 tab 标签：默认（桌面）只显示长标签，短标签由文件末尾的窄屏媒体查询打开。
   两个 span 在模板里紧挨着写，中间没有空白 —— 桌面端文字与改前逐字相同。 */
.tab-label-short { display: none; }

.tab-section .section-more { padding-bottom: 12px; }

.tab-panels {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.tab-panel { display: none; }

.tab-panel.active {
  display: flex;
  flex-direction: column;
  flex: 1;
  animation: tabFade .26s ease;
}

@keyframes tabFade {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}

.tab-panel .res-list { flex: 1; }

/* 全宽框内的条目：标题靠左、元信息靠右，撑满整行 */
.tab-section .res-item {
  align-items: center;
  padding: 13px 24px;
}

.tab-section .res-body {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 28px;
}

.tab-section .res-title {
  flex: 1;
  min-width: 0;
  font-size: var(--fs-base);
}

.tab-section .res-meta {
  margin-top: 0;
  flex-shrink: 0;
  gap: 18px;
}

.tab-section .res-badge,
.tab-section .res-rank { margin-top: 0; }

/* 资源列表项 */

.res-list { list-style: none; margin: 0; padding: 6px 0; flex: 1; }

.res-item {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 9px 20px;
  transition: background .14s;
}

.res-item:hover { background: #fafcfb; }

.res-item + .res-item { border-top: 1px solid var(--border-2); }

.res-badge {
  flex-shrink: 0;
  min-width: 44px;
  height: 22px;
  padding: 0 7px;
  border-radius: 4px;
  font-size: var(--fs-xs);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 2px;
  letter-spacing: .3px;
}

.res-body { flex: 1; min-width: 0; }

.res-title {
  display: block;
  font-size: var(--fs-base);
  font-weight: 500;
  line-height: 1.5;
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.res-item:hover .res-title { color: var(--primary); }

.res-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 3px;
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.res-meta .pts {
  color: #b45309;
  font-weight: 500;
}
.res-meta .pts.free { color: var(--primary); }

.res-rank {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  font-size: var(--fs-2xs);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--border-2);
  color: var(--text-3);
  margin-top: 3px;
}
.res-rank.top1 { background: #b91c1c; color: #fff; }
.res-rank.top2 { background: #c2410c; color: #fff; }
.res-rank.top3 { background: #a16207; color: #fff; }

.empty-tip {
  padding: 40px 20px;
  text-align: center;
  color: var(--text-3);
  font-size: var(--fs-base);
}

/* ------------------------------ 列表页 ------------------------------ */

.page-head {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 22px 24px;
  margin-bottom: 18px;
}

.page-head h1 {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: 600;
}

.page-head .desc {
  margin: 6px 0 0;
  color: var(--text-2);
  font-size: var(--fs-base);
}

.filter-bar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border-2);
  flex-wrap: wrap;
}

.filter-bar .lbl { font-size: var(--fs-sm); color: var(--text-3); margin-right: 2px; }
/* 「标签分类」筛选条：**固定只占一行**，放不下的裁掉，行末的「更多」链到 /tags 看全部。
   （2026-10-12：原来的「一行 → 三行 → 全部」折叠已取消，按钮也从 <button> 改成 <a>。）
   max-height 由 JS 实测行高后写入（见 public/js/main.js 第二个 IIFE）—— 这里故意不写死数值，
   所以关掉 JS 时整条会自然铺开显示，不会把标签藏起来（渐进增强）。
   「更多」按钮虽然也进了 .chips，但那是 JS 挪进去的，父级仍然只有 .chips 一个子元素。 */
.filter-bar--clamp { display: block; }
.filter-bar--clamp .chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  /* ⚠️ 必须显式写 flex-start。flex-wrap 的默认 align-content 是 stretch，
     而容器又被 max-height 卡住时，浏览器会把**每一行压扁**去凑容器高度 ——
     结果是标签被从中间截断、行位置全部错位。写成 flex-start 后每行保持自然高度，
     超出的部分被 overflow 干净地切掉。 */
  align-content: flex-start;
}
.filter-bar--clamp.is-clamped .chips { overflow: hidden; }

/* 「展开 / 更多 / 收起」按钮：2026-10-06 起不再独占一行 ——
   main.js 把它挪进 .chips 里跟 chip 同一行（折叠时坐第一行最后、展开后坐最后一行最后）。
   ⚠️ 所以**不能**再有 margin-top：.chips 是 align-items:center，那 8px 会把它往下顶。
   ⚠️ flex:none + nowrap 是必须的：它是 flex 子项，否则会被压缩/换行，按钮文字被折断。 */
.chips-toggle {
  flex: none;
  white-space: nowrap;
  padding: 0 2px;
  border: 0;
  background: none;
  font-size: var(--fs-sm);
  color: var(--primary);
  cursor: pointer;
  /* 2026-10-12：从 <button> 变成 <a>，浏览器默认会给下划线，这里去掉（hover 时再出现）。 */
  text-decoration: none;
}
.chips-toggle:hover { text-decoration: underline; }
/* 2026-10-12：从「展开 / 收起」按钮改成跳转 /tags 的「更多」链接 ——
   箭头由「向下展开 ▾」换成「指向右 ›」，data-dir 两态随折叠一起删除。 */
.chips-toggle::after { content: ' \203A'; font-size: var(--fs-2xs); }

/* B批（2026-10-11）：/list 次要筛选（资料属性/文件大小/下载积分）移动端可收起。
   仅 JS 在 ≤640px 时给 #filterExtra 加 .is-collapsed 收起，并显露「筛选」按钮；
   桌面端按钮 hidden、组始终展开；关 JS 时两者都不动 → 内容照常可见（渐进增强）。 */
.filter-extra.is-collapsed { display: none; }
.filter-toggle {
  display: inline-block;
  margin: 6px 0 0;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: none;
  font-size: var(--fs-sm);
  color: var(--primary);
  cursor: pointer;
}
.filter-toggle[hidden] { display: none; }
.filter-toggle::after { content: ' \25BE'; font-size: var(--fs-2xs); }
.filter-toggle[aria-expanded="true"]::after { content: ' \25B4'; font-size: var(--fs-2xs); }
.cat-pos {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-sm);
  color: var(--text-3);
  margin-bottom: 12px;
}
.cat-pos a {
  color: var(--text-3);
  text-decoration: none;
  transition: color .12s;
}
.cat-pos a:hover { color: var(--primary); }
.cat-pos-sep { color: var(--border); }
.cat-pos-cur {
  color: var(--text);
  font-weight: 600;
}
.cat-pos-back {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 12px;
  background: var(--primary-soft);
  color: var(--primary-dark) !important;
  font-size: var(--fs-xs);
}
.cat-pos-back:hover { background: var(--primary); color: #fff !important; }

.chip {
  padding: 5px 13px;
  border: 1px solid var(--border);
  border-radius: 15px;
  font-size: var(--fs-sm);
  color: var(--text-2);
  background: #fff;
}
.chip:hover { border-color: var(--primary-line); color: var(--primary); background: var(--primary-soft); }
.chip.active { background: var(--primary); border-color: var(--primary); color: #fff; }

/* ══════════ mobileux-20261008 列表页筛选条可读性（方案 P2）══════════
   改前实测对比度（WCAG AA 正文需 4.5:1）：
     .filter-bar .lbl 文字 #93a1ae 对白底 = 2.64:1
     .chip 边框 #e6eaec = 1.21:1 ；.filter-bar 上边框 #eef1f2 = 1.10:1
   且分类名与选项同为 13px/400，零层级差 —— 用户反馈「难以清晰区分」。
   P2：分类名做成灰底小标签（#4a5b6b on #eef2f4 = 6.12:1，过 AA），选项边框加深。
   ⚠️ 只改配色/字号/内边距，绝不动 .chip 的尺寸与换行 —— public/js/main.js
      第二个 IIFE 靠 .chip 的 top 去重来算「标签分类」条的折叠行高。
      实测 .lbl 变高后（21→26px）仍矮于 .chip（33.44px），该测量不受影响
      （1280px 下 barH / chipRows 全部不变）。 */
.filter-bar { border-top: 1px solid #dfe6e9; }
.filter-bar .lbl {
  font-size: var(--fs-xs);
  font-weight: 600;
  color: #4a5b6b;
  background: #eef2f4;
  border-radius: 4px;
  padding: 3px 8px;
  min-width: 60px;
  text-align: center;
  margin-right: 4px;
}
.chip { border-color: #cfd9de; }

.content-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

/* 列表行（大） */

.row-item {
  display: flex;
  gap: 16px;
  padding: 18px 22px;
  transition: background .14s;
}
.row-item + .row-item { border-top: 1px solid var(--border-2); }
.row-item:hover { background: #fafcfb; }
.row-item.is-clickable { cursor: pointer; }

.row-icon {
  flex-shrink: 0;
  width: 46px;
  height: 46px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: .3px;
}

.row-main { flex: 1; min-width: 0; }

.row-title {
  font-size: var(--fs-md);
  font-weight: 600;
  line-height: 1.5;
  margin: 0 0 5px;
}
.row-item:hover .row-title { color: var(--primary); }

.row-summary {
  margin: 0 0 9px;
  color: var(--text-2);
  font-size: var(--fs-base);
  line-height: 1.6;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.row-meta {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: var(--fs-xs);
  color: var(--text-3);
}

.row-meta .cat {
  color: var(--primary);
  background: var(--primary-soft);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: var(--fs-xs);
}

.tag-mini {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 4px;
  font-size: var(--fs-xs);
  line-height: 1.6;
}

.row-action { flex-shrink: 0; display: flex; align-items: center; }

/* ------------------------------ 分页 ------------------------------ */

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 24px 0 4px;
  flex-wrap: wrap;
}

.pager a, .pager span {
  min-width: 34px;
  height: 34px;
  padding: 0 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--text-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-base);
}
.pager a:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.pager .cur { background: var(--primary); border-color: var(--primary); color: #fff; font-weight: 600; }
.pager .dots { border: 0; background: transparent; color: var(--text-2); }
.pager .disabled { color: #cbd5e1; background: #fafbfb; }

/* ------------------------------ 详情页 ------------------------------ */

.detail-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 18px;
  align-items: start;
}

.detail-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  /* 顶部 padding 30 → 22px：与紧贴的面包屑更协调，避免大空白 */
  padding: 22px 32px 30px;
}

/* ---- 键值列表（2026-10-12）------------------------------------------------
   ⚠️ 原本只在 admin.css 里定义 → 前台不加载 admin.css，导致 contact / help / go /
   user-upload 四个页面的 .kv-list 完全没样式（标签与值粘连成「邮箱abc@x.com」）。
   这里补一份与后台一致的规则。全部使用处都在 .detail-card（纯白底）内，
   故标签色可用 --text-3（白底 4.76:1 达标）。 */
.kv-list { padding: 4px 0; }
.kv-list .kv {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border-2);
  font-size: var(--fs-base);
}
.kv-list .kv:last-child { border-bottom: 0; }
.kv-list .kv .k { color: var(--text-3); flex-shrink: 0; }
.kv-list .kv .v { text-align: right; word-break: break-all; }

.detail-card h1 {
  margin: 0 0 12px;
  font-size: var(--fs-2xl);
  font-weight: 600;
  line-height: 1.5;
}

.detail-meta {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--border-2);
  font-size: var(--fs-sm);
  color: var(--text-3);
}

.detail-meta .sep { color: var(--border); }

.detail-summary {
  margin: 20px 0;
  padding: 16px 18px;
  background: #fafcfb;
  border-left: 3px solid var(--primary-line);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  font-size: var(--fs-base);
  line-height: 1.75;
  /* summary-wrap-20261007 保留摘要里的换行：后台摘要实测 66/99 条含回车换行，
     原来被 HTML 折叠成空格，详情页会挤成一整段。 */
  white-space: pre-wrap;
  /* 防超长无空格串（长 URL / 英文长串）撑破容器 */
  overflow-wrap: break-word;
}

.detail-tags {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-bottom: 22px;
}

.file-panel {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  background: #fcfdfd;
}

.file-panel-head {
  display: flex;
  align-items: center;
  gap: 14px;
  padding-bottom: 18px;
  margin-bottom: 18px;
  border-bottom: 1px dashed var(--border);
}

.file-panel-head .fi {
  width: 52px;
  height: 52px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: var(--fs-xs);
  flex-shrink: 0;
}

.file-panel-head .fname {
  font-size: var(--fs-base);
  font-weight: 600;
  word-break: break-all;
  margin-bottom: 3px;
}

.file-panel-head .fsize { font-size: var(--fs-xs); color: var(--text-3); }

.dl-action {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}

.dl-cost {
  font-size: var(--fs-base);
  color: var(--text-2);
}
.dl-cost b { color: #b45309; font-size: var(--fs-lg); }
.dl-cost b.free { color: var(--primary); }

/* 在线预览入口（2026-10-19）。放在 .dl-action 之外，
   所以「积分不足 / 会员额度用完 / 免费」等所有下载分支下它都照样显示 ——
   预览本身不花钱，不该被下载门槛挡住。 */
.dl-preview-row {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
}
.dl-preview-hint { font-size: var(--fs-xs); color: var(--text-2); }
.dl-preview-hint b { color: var(--primary); font-weight: 600; }
@media (max-width: 720px) {
  .dl-preview-row { width: 100%; }
  .dl-preview-row .btn { flex: 1; justify-content: center; }
}

/* 二级操作行：收藏 + 浏览/下载计数。
   收藏按钮采用 outline 主色，比「立即下载」视觉重量低一档，引导用户先存后下。 */
.dl-extras {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  margin-top: 12px;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.fav-form { display: inline-flex; margin: 0; }
.fav-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text-2);
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s, transform .1s;
}
.fav-btn:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-soft); }
.fav-btn:active { transform: scale(.96); }
.fav-btn.is-on {
  border-color: var(--primary);
  background: var(--primary-soft);
  color: var(--primary);
  font-weight: 500;
}
.fav-btn.is-on:hover { background: #e1f1ec; }
.fav-btn .fav-icon { transition: transform .2s; }
.fav-btn.is-on .fav-icon { transform: scale(1.08); }
.fav-cnt { font-size: var(--fs-xs); opacity: .65; margin-left: 2px; }
.dl-meta-mini {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.dl-meta-mini svg { color: var(--text-3); }

/* 用户中心快捷入口卡片：图标 + 标题 + 副标题 + 角标 */
.quick-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}
.ql-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: #fff;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  transition: border-color .14s, box-shadow .14s, transform .14s;
}
.ql-card:hover {
  border-color: var(--primary-line);
  box-shadow: 0 4px 12px rgba(var(--primary-rgb), .08);
  transform: translateY(-1px);
  color: var(--primary);
}
.ql-ic {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.ql-card:hover .ql-ic { background: var(--primary); color: #fff; }
.ql-text { display: flex; flex-direction: column; min-width: 0; }
.ql-title { font-size: var(--fs-base); font-weight: 600; }
.ql-sub { font-size: var(--fs-xs); color: var(--text-3); margin-top: 1px; }
.ql-card:hover .ql-sub { color: var(--primary); opacity: .8; }
.ql-badge {
  position: absolute;
  top: 8px;
  right: 10px;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 9px;
  background: var(--primary);
  color: #fff;
  font-size: var(--fs-2xs);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-variant-numeric: tabular-nums;
}

/* 详情页底部的失效反馈 + 内容有误入口 */
.dead-report {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border-2);
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  font-size: var(--fs-xs);
}
.dead-report-btn {
  background: none;
  border: 0;
  color: var(--text-3);
  font-size: var(--fs-xs);
  cursor: pointer;
  padding: 0;
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
.dead-report-btn:hover { color: var(--primary); }
.dead-report-link {
  color: var(--text-3);
  text-decoration: none;
  font-size: var(--fs-xs);
}
.dead-report-link:hover { color: var(--primary); }

/* ------------------------------ 收藏列表（用户中心 /user/favorites） ------------------------------ */
.fav-list { list-style: none; margin: 0; padding: 0; }
.fav-item {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 20px;
  border-bottom: 1px solid var(--border-2);
  flex-wrap: wrap;
}
.fav-item:last-child { border-bottom: 0; }
.fav-item:hover { background: #fafcfb; }
.fav-title {
  flex: 1 1 240px;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.fav-title:hover { color: var(--primary); }
.fav-title.is-deleted { color: var(--text-3); cursor: default; }
.fav-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: var(--fs-xs);
  color: var(--text-3);
  flex-wrap: wrap;
}
.fav-cat-tag {
  background: var(--primary-soft);
  color: var(--primary);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: var(--fs-xs);
  font-weight: 500;
}
.fav-actions { display: flex; gap: 6px; flex-shrink: 0; }


/* ------------------------------ 增强 pager：页码 + 跳页信息 ------------------------------ */
.pager .pager-info {
  margin-left: 8px;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.pager .ellipsis {
  padding: 0 4px;
  color: var(--text-3);
}

/* ------------------------------ 下载成功 toast ------------------------------ */
.dl-toast {
  position: fixed;
  top: 20px;
  right: 20px;
  z-index: 9999;
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: #fff;
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  padding: 14px 16px 14px 14px;
  min-width: 280px;
  max-width: 360px;
  opacity: 0;
  transform: translateX(20px);
  transition: opacity .25s, transform .25s;
  font-size: var(--fs-sm);
  color: var(--text);
}
.dl-toast.show { opacity: 1; transform: translateX(0); }
.dl-toast-icon {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-base);
  font-weight: 700;
}
.dl-toast-body { flex: 1; min-width: 0; }
.dl-toast-title { font-weight: 600; font-size: var(--fs-base); margin-bottom: 4px; }
.dl-toast-meta { color: var(--text-2); font-size: var(--fs-xs); }
.dl-toast-actions { margin-top: 6px; display: flex; gap: 12px; }
.dl-toast-link {
  font-size: var(--fs-xs);
  color: var(--primary);
  text-decoration: none;
}
.dl-toast-link:hover { text-decoration: underline; }
.dl-toast-close {
  border: 0;
  background: transparent;
  color: var(--text-3);
  cursor: pointer;
  font-size: var(--fs-lg);
  line-height: 1;
  padding: 0 4px;
}
.dl-toast-close:hover { color: var(--text); }


/* 一次性下载引导卡：登录态/积分不足时复用同一布局。
   左侧醒目数字 + 说明，右侧行动按钮组 —— 用户一眼看清「为什么下不了」+「下一步」。 */
.dl-gate {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-left: 3px solid #f59e0b;
  border-radius: var(--radius-sm);
  padding: 14px 18px;
}
.dl-gate-main { flex: 1; min-width: 200px; }
.dl-gate-cost {
  display: flex;
  align-items: baseline;
  gap: 4px;
  margin-bottom: 4px;
}
.dl-gate-cost-label { font-size: var(--fs-sm); color: #92400e; }
.dl-gate-cost-num {
  font-size: var(--fs-2xl);
  font-weight: 700;
  color: #b45309;
  line-height: 1;
}
.dl-gate-cost-num.free { color: var(--primary); font-size: var(--fs-lg); }
.dl-gate-cost-unit { font-size: var(--fs-sm); color: #92400e; }
.dl-gate-sub { font-size: var(--fs-xs); color: #92400e; opacity: .85; }
.dl-gate-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.dl-gate-link {
  font-size: var(--fs-xs);
  color: #92400e;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.dl-gate-link:hover { color: var(--primary); }
.dl-gate-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-sm);
  color: #92400e;
  margin-right: 4px;
}
.dl-gate-progress b { color: #b45309; font-size: var(--fs-md); }
.dl-gate-progress-bar {
  position: relative;
  width: 80px;
  height: 6px;
  background: #fde68a;
  border-radius: 999px;
  overflow: hidden;
}
.dl-gate-progress-fill {
  display: block;
  height: 100%;
  background: #b45309;
  border-radius: 999px;
  transition: width .3s;
}
/* ↓ 以下 @media (max-width: 640px) 由 3 处分散的块合并而来（2026-10-07 断点收敛）。
   合并位置刻意选在**原最后一块**处 —— 保证各断点之间的相对先后不变。 */
@media (max-width: 640px) {
  .hero-inner { padding: 22px 16px 16px; }
  .hero-title { font-size: var(--fs-xl); }
  .hero-subtitle { font-size: var(--fs-xs); margin-bottom: 12px; }
  .hero-search input { height: 42px; padding: 0 48px 0 16px; font-size: var(--fs-base); }
  .hero-search-btn { width: 32px; height: 32px; right: 4px; }
  .hero-search-btn svg { width: 16px; height: 16px; }
  .hero-hot { font-size: var(--fs-xs); line-height: 1.85; margin-bottom: 12px; }
  .hero-stats { flex-wrap: wrap; justify-content: center; }
  .hero-stat { padding: 0 10px; font-size: var(--fs-xs); }

  .fav-item { flex-direction: column; align-items: flex-start; }
  .fav-title { width: 100%; }
  .fav-actions { width: 100%; }
  .fav-actions form, .fav-actions .btn { flex: 1; }

  .dl-gate { flex-direction: column; align-items: flex-start; }
  /* ⚠️⚠️ 必须放开 min-width（2026-10-14）：
     桌面规则 .dl-gate-main{min-width:200px} 在 320px 手机上会把卡片撑破 ——
     那时 .dl-gate 内容区只有 168px（视口 320 − 页面边距 − 卡片 padding 36 − 边框 4），
     min-width:200px 让 .dl-gate-main 硬占 200px → 右越界 32px，
     连带里面的「扫码支付 ¥X 立即下载」按钮一起跑到卡片外面（杨哥报的那个现象）。
     ⚠️ 只挂 .btn-wrap 不够：320px 时按钮能折行了，但 .dl-gate-main 仍然 200px。 */
  .dl-gate-main { min-width: 0; }
  .dl-gate-progress { width: 100%; }

  /* 「立即下载」在窄屏强制落到第二行（2026-10-14 杨哥要求）。
     详情页那两颗「扫码支付 ¥X 立即下载」按钮里，把「立即下载」包进 span.btn-l2；
     这里只在手机端让它独占一整行。
     ⚠️⚠️ 不能写 display:block —— .btn 是 inline-flex，子元素一律被「块级化」，
        display 算什么都是 block，写 block 等于没写，永远换不了行（实测：390px 下
        按钮高度纹丝不动 44px，就是栽在这儿）。
        正解是让它占满一整行的 flex 基准 + 让容器允许换行（.btn-wrap 里已加 flex-wrap:wrap）。
     ⚠️ 必须放在 @media 里 —— PC 上按钮宽、一行放得下，硬换行会白占一行。
     ⚠️ 也不能只靠 .btn-wrap 的自然折行：那是「允许折行」，能不能断在「立即下载」
        前面取决于剩余宽度，¥ 金额变长（如 ¥12.00）时就断不到那里。 */
  .btn-l2 { flex: 0 0 100%; }
}

.alert {
  padding: 11px 15px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  margin-bottom: 16px;
}
.alert-warn { background: #fffbeb; border: 1px solid #fde68a; color: #92400e; }
.alert-info { background: var(--primary-soft); border: 1px solid var(--primary-line); color: var(--primary-dark); }
.alert-success { background: #f0fdf4; border: 1px solid #bbf7d0; color: #166534; }

/* 侧栏 */

.crumbs {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  font-size: var(--fs-sm);
  color: var(--text-2);
  /* 详情页：与下方正文卡片收紧间距（原 18px → 10px），
     否则面包屑 + h1 之间的呼吸感太重，长标题尤其显得松散。 */
  margin-bottom: 10px;
}
.crumbs a {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--text-2);
  text-decoration: none;
  transition: color .12s;
}
.crumbs a:hover { color: var(--primary); }
.crumbs .crumb-home {
  width: 24px; height: 24px;
  border-radius: 6px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  justify-content: center;
}
.crumbs .crumb-home:hover { background: var(--primary); color: #fff; }
.crumbs .crumb-sep {
  width: 14px; height: 14px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2393a1ae' stroke-width='2.5' stroke-linecap='round'><path d='M9 6l6 6-6 6'/></svg>");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 14px 14px;
  opacity: .8;
}
.crumbs .cur {
  color: var(--text);
  font-weight: 500;
  max-width: 360px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.side-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 16px;
}

.side-card h3 {
  margin: 0;
  padding: 14px 18px;
  font-size: var(--fs-base);
  font-weight: 600;
  border-bottom: 1px solid var(--border-2);
  display: flex;
  align-items: center;
  gap: 8px;
}
.side-card h3::before {
  content: '';
  width: 3px;
  height: 13px;
  border-radius: 2px;
  background: var(--primary);
}

.side-list { list-style: none; margin: 0; padding: 8px 0; }
.side-list li a {
  display: flex;
  gap: 9px;
  padding: 7px 18px;
  font-size: var(--fs-base);
  color: var(--text-2);
  line-height: 1.5;
}
.side-list li a:hover { color: var(--primary); background: #fafcfb; }
.side-list .idx {
  flex-shrink: 0;
  width: 17px;
  height: 17px;
  border-radius: 3px;
  background: var(--border-2);
  color: var(--text-2);
  font-size: var(--fs-2xs);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 3px;
}
.side-list .idx.hot { background: var(--primary); color: #fff; }

.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 16px 18px;
}
.tag-cloud a {
  padding: 4px 11px;
  border-radius: 13px;
  font-size: var(--fs-xs);
  /* 行高写死：首页要按「最多 3 行」裁剪，chip 高度必须可预测（20 + 4×2 = 28px）。
     跟着 body 的 1.65 走的话，字体的细微差异会让 3 行的总高对不上。 */
  line-height: 20px;
  background: #f4f7f6;
  color: var(--text-2);
}
.tag-cloud a:hover { background: var(--primary-soft); color: var(--primary); }

/* 首页「标签分类」：最多 3 行（2026-10-06 需求）。
   3 行 = 28×3 + 8×2 = 100px，加上下 padding 16×2 = 132px。
   ⚠️ 只能用 max-height + overflow 裁，不能用 -webkit-line-clamp ——
      那是给「单块文本」用的，对 flex-wrap 出来的多行子元素不生效。
   ⚠️ 改动 chip 的 padding / 字号 / gap 时这个数字必须跟着改，
      否则第 4 行会露出半行，看起来像被切坏了。 */
.tag-cloud--rows3 {
  max-height: 132px;
  overflow: hidden;
}

/* --------------------- 属性方框（资料属性 / 下载积分 / 资源大小） ---------------------
   2026-10-06 改造：原来是「2 列大卡片 + 44px 色块图标」，8 个属性要占 4 行。
   杨哥要求换成小方框、两行内列举完。现在用 auto-fill 自适应列数：
   1200px 宽下每行约 8 个 —— 资料属性 8 个正好一行，积分/大小 6 个也是一行。
   ⚠️ 必须写 minmax(…, 1fr) 而不是固定宽度：固定宽度在窄屏会横向溢出。
   ⚠️ 用 auto-fill 而不是 auto-fit：auto-fit 会把 6 个档位的方框拉得很宽，
      和 8 个属性的那一行宽度对不齐，三块看起来不成套。 */
.attr-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(124px, 1fr));
  gap: 10px;
  padding: 16px 18px;
}
.attr-box {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
  padding: 9px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  font-size: var(--fs-base);
  color: var(--text);
  transition: border-color .15s, background .15s, color .15s;
}
.attr-box:hover {
  border-color: var(--primary);
  background: var(--primary-soft);
  color: var(--primary-dark);
}
.attr-name {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.attr-cnt {
  flex-shrink: 0;
  font-size: var(--fs-xs);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.attr-box:hover .attr-cnt { color: var(--primary); }
/* 0 份的档位照样显示（杨哥要「全部档位都显示」），但视觉上弱化，
   一眼能看出「这个分类现在还没有内容」。 */
.attr-box.is-empty { color: var(--text-3); background: #fafbfb; }

/* ↓ 以下 @media (max-width: 480px) 由 2 处分散的块合并而来（2026-10-07 断点收敛）。
   合并位置刻意选在**原最后一块**处 —— 保证各断点之间的相对先后不变。 */
@media (max-width: 480px) {
  .dl-toast { left: 16px; right: 16px; max-width: none; min-width: 0; }

  /* 窄屏：两列。8 个属性在 375px 下必然要排 4 行 —— 塞不下更多，
     这是屏幕宽度决定的，不是没做响应式。 */
  .attr-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 12px; }
  .attr-box { padding: 8px 10px; font-size: var(--fs-sm); }
}

/* ------------------------------ 相关主题（详情页主区下方 · 两栏标题列表） ------------------------------
   只列标题：单行显示，超出栏宽用省略号；完整标题由 <a title="…"> 在悬停时给出。
   ⚠️ 栅格必须写 minmax(0, 1fr)：写成 1fr（= minmax(auto, 1fr)）时，auto 的最小尺寸
      就是 nowrap 文本的宽度，列会被长标题撑开、省略号永远不出现（实测过）。 */

.related-row {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px 18px 14px;
  margin-top: 18px;
}
.related-row .section-head {
  padding: 12px 0 14px;
  border-bottom: 1px solid var(--border-2);
  margin-bottom: 12px;
}
.related-cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 26px;
  padding: 0 0 4px;
}
.related-cols.is-single { grid-template-columns: minmax(0, 1fr); }
.related-col { list-style: none; margin: 0; padding: 0; }
.related-col li { min-width: 0; }
.related-col a {
  display: block;
  padding: 8px 10px;
  border-radius: 6px;
  font-size: var(--fs-base);
  color: var(--text-2);
  text-decoration: none;
  line-height: 1.6;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.related-col a::before {
  content: '·';
  color: var(--primary);
  font-weight: 700;
  margin-right: 8px;
}
.related-col a:hover { color: var(--primary); background: #fafcfb; }


/* ------------------------------ 网盘 / 外部链接标记 ------------------------------ */

.res-badge.netdisk {
  background: #e0f2fe;
  color: #0369a1;
  min-width: 36px;
}

.netdisk-mini {
  display: inline-block;
  padding: 1px 7px;
  border-radius: 4px;
  background: #e0f2fe;
  color: #0369a1;
  font-size: var(--fs-xs);
  font-weight: 600;
}

/* ------------------------------ 标签列表页 ------------------------------ */

.label-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}

.label-card {
  display: block;
  padding: 14px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: #fff;
  transition: border-color .16s, box-shadow .16s, transform .16s;
}
.label-card:hover {
  border-color: var(--primary-line);
  box-shadow: var(--shadow-hover);
  transform: translateY(-1px);
  color: inherit;
}

.label-card .label-name {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: var(--fs-md);
  font-weight: 600;
}
.label-card .label-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.label-card .label-cnt {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.label-card .label-desc {
  display: block;
  margin-top: 7px;
  font-size: var(--fs-xs);
  color: var(--text-2);
  line-height: 1.6;
}

/* 标签页热门云：卡片式背景，按关联数分三档字号 */
.tags-hot-card {
  background: linear-gradient(135deg, #fff, rgba(var(--primary-rgb), .03));
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 18px 22px 20px;
  margin-bottom: 18px;
}
.tags-hot-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 12px;
}
.tags-hot-head h2 {
  font-size: var(--fs-md);
  font-weight: 600;
  margin: 0;
}
.tags-hot-sub {
  font-size: var(--fs-xs);
  color: var(--text-2);
}
.tag-cloud-hot {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 12px;
  align-items: center;
}
.hot-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 12px;
  border-radius: 18px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  text-decoration: none;
  transition: transform .12s, background .12s, box-shadow .12s;
  line-height: 1.2;
}
.hot-tag:hover {
  background: var(--primary);
  color: #fff;
  transform: translateY(-1px);
  box-shadow: 0 4px 10px rgba(var(--primary-rgb), .22);
}
.hot-tag .hot-tag-name { font-weight: 600; }
.hot-tag .hot-tag-cnt {
  font-size: var(--fs-xs);
  /* 坐在主题色淡底（最深 #d5e6e3）上，--text-2 也只有 4.23 —— 用与标签名同色系的深色 */
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}
.hot-tag:hover .hot-tag-cnt { color: #fff; }
.hot-tag.lv-1 { font-size: var(--fs-sm); padding: 5px 10px; }
.hot-tag.lv-2 { font-size: var(--fs-md); padding: 7px 14px; }
.hot-tag.lv-3 {
  font-size: var(--fs-xl);
  padding: 9px 16px;
  background: rgba(var(--primary-rgb), .14);
  box-shadow: 0 1px 3px rgba(var(--primary-rgb), .10);
}
.hot-tag.lv-3 .hot-tag-cnt { font-size: var(--fs-xs); }
.tags-rest-head {
  font-size: var(--fs-base);
  font-weight: 600;
  margin: 4px 0 12px;
  padding-left: 8px;
  border-left: 3px solid var(--primary);
}
.tags-rest-head .muted { font-weight: 400; color: var(--text-3); font-size: var(--fs-sm); margin-left: 4px; }

/* tagpage-20261008 标签页改版：说明区合并 / 热门云限高（宽屏1行·窄屏3行）/ 其他标签行式列表（桌面4列） */

/* 原独立的「标签页说明卡」并进 page-head，用一条分隔线跟统计行区分开 */
.page-head-intro {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-2);
  color: var(--text-2);
  font-size: var(--fs-base);
  line-height: 1.75;
}
.page-head-intro > *:first-child { margin-top: 0; }
.page-head-intro > *:last-child { margin-bottom: 0; }

/* 热门云限高：JS 给容器加 .is-single 后按「行数上限」裁剪整块
   （宽屏 1 行 / 窄屏 3 行，见 main.js 的 MAX_ROWS_WIDE / MAX_ROWS_NARROW）。
   ⚠️ 子项必须 flex-shrink:0 —— 否则 flex 会把 chip 压扁，
   JS 量到的宽度就是假的，裁剪位置全错。
   放不下的整块由 JS 挪进下方「其他标签」列表（不出现半截标签）。 */
.tag-cloud-hot.is-single {
  overflow: hidden;
  padding: 6px 0;
  margin: -6px 0;
}
.tag-cloud-hot.is-single .hot-tag { flex-shrink: 0; }

/* 其他标签：一行一个标签，只显示「标签名 + 数量」。
   桌面 5 列 / 平板 2 列 / 手机 1 列。
   ⚠️ 桌面列数改了**必须同步改 views/front/tags.ejs 里的 PER_KIND**
      （= 列数 × 3 行，现为 5 × 3 = 15），否则「展开更多」的阈值对不上实际行数。 */
.tag-rows {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 28px;
}
@media (min-width: 861px) {
  .tag-rows { grid-template-columns: repeat(5, minmax(0, 1fr)); column-gap: 20px; }
}
.tag-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  padding: 9px 2px;
  border-bottom: 1px solid var(--border-2);
  text-decoration: none;
}
.tag-row:hover { background: #f7faf9; }
.tag-row:hover .tag-row-name { color: var(--primary-dark); }
.tag-row-name {
  font-size: var(--fs-base);
  color: var(--text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tag-row-cnt {
  margin-left: auto;
  flex-shrink: 0;
  font-size: var(--fs-xs);
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
/* 关联 0 条资料的标签：灰一点，一眼能看出是空的 */
.tag-row.is-empty .tag-row-name { color: var(--text-3); }
.tag-row.is-empty .tag-row-cnt { opacity: .7; }

.tag-rows-more { text-align: center; margin-top: 14px; }
.tag-more-btn {
  padding: 7px 24px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text-2);
  font-family: inherit;
  font-size: var(--fs-sm);
  cursor: pointer;
  transition: border-color .16s, color .16s;
}
.tag-more-btn:hover { border-color: var(--primary-line); color: var(--primary-dark); }

@media (max-width: 640px) {
  .tag-rows { grid-template-columns: 1fr; }
  .content-card .tag-rows { column-gap: 0; }
}

/* ══════════ 批 B（2026-10-10）标签分类：/tags 分组 · 首页分行 · 换个维度看 ══════════
   ⚠️ 这里全部是**新增类名**（tags-kind* / tag-kind* / tag-cloud--kind / kind-badge /
      tag-dimbar*），不改任何既有规则 —— 所以放在文件这个位置不会影响别的页面。
   ⚠️ 这些样式都只是「好看」层面的：类目区、维度条**不靠 CSS 才可见**
      （元素默认就是可见的），CSS 万一没加载也不会出现「空白方块」。 */

/* --- /tags 页：每个类目一个区（同一个 content-card 内用分隔线切开） --- */
.tags-kind {
  padding: 14px 0 6px;
  border-top: 1px solid var(--border-2);
}
.tags-kind:first-child { padding-top: 0; border-top: 0; }
.tags-kind-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 10px;
}
.tags-kind-head h2 {
  margin: 0;
  padding-left: 8px;
  border-left: 3px solid var(--primary);
  font-size: var(--fs-base);
  font-weight: 600;
}
/* 类目名右侧的数量角标 */
.tags-kind-num {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
}

/* --- 首页「标签分类」：按类目分行 --- */
.tag-kinds { padding: 6px 18px 14px; }
.tag-kind-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 7px 0;
}
.tag-kind-row + .tag-kind-row { border-top: 1px dashed var(--border-2); }
/* ⚠️ 固定宽度让各行的标签起点对齐成一列；类目名过长时省略号 + title 给全名。
   「会议活动标签」6 字 ≈ 75px，80px 放得下。 */
.tag-kind-name {
  flex: 0 0 80px;
  width: 80px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--primary-dark);
  text-decoration: none;
}
.tag-kind-name:hover { color: var(--primary); }
/* 覆盖 .tag-cloud 自带的 padding —— 这里是嵌在 .tag-kind-row 里的，不需要内边距 */
.tag-cloud--kind {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0;
  gap: 6px;
}

/* --- /tag/<slug> 页：h1 旁的类目徽章 + 「换个维度看」一行 --- */
.kind-badge {
  display: inline-block;
  vertical-align: middle;
  margin-left: 8px;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: var(--fs-xs);
  font-weight: 500;
}
.tag-dimbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin-top: 12px;
  padding: 10px 14px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  background: #fbfdfc;
  font-size: var(--fs-sm);
}
.tag-dimbar-lbl {
  flex-shrink: 0;
  font-weight: 600;
  color: var(--text-2);
}
.tag-dimbar-group { display: inline-flex; align-items: center; gap: 7px; }
.tag-dimbar-kind {
  flex-shrink: 0;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: var(--fs-xs);
}
.tag-dimbar-group a {
  color: var(--text-2);
  text-decoration: none;
  border-bottom: 1px dashed var(--border);
  padding-bottom: 1px;
}
.tag-dimbar-group a:hover { color: var(--primary); border-bottom-color: var(--primary); }

/* 窄屏：类目名不再固定 80px（那样标签区只剩很窄一条），改成类名一行、标签另起一行。
   ⚠️ 这是**新增的独立断点块**，只含新类名 —— 不参与既有 8 个断点块的先后关系。 */
@media (max-width: 640px) {
  .tag-kind-row { display: block; }
  .tag-kind-name { display: block; width: auto; margin-bottom: 6px; }
  .tag-dimbar { padding: 9px 11px; font-size: var(--fs-xs); }
  .tag-dimbar-group { gap: 5px; }
}


/* ------------------------------ 富文本（后台可编辑的 HTML 内容） ------------------------------ */

.rich-text { color: var(--text-2); line-height: 1.9; font-size: var(--fs-base); }
.rich-text > *:first-child { margin-top: 0; }
.rich-text > *:last-child { margin-bottom: 0; }
.rich-text h1, .rich-text h2 { font-size: var(--fs-xl); color: var(--text); margin: 24px 0 10px; font-weight: 700; }
.rich-text h3 { font-size: var(--fs-md); color: var(--text); margin: 22px 0 10px; font-weight: 600; }
.rich-text h4 { font-size: var(--fs-base); color: var(--text); margin: 18px 0 8px; font-weight: 600; }
.rich-text p { margin: 0 0 13px; }
.rich-text ul, .rich-text ol { margin: 0 0 14px; padding-left: 22px; }
.rich-text li { margin-bottom: 5px; }
.rich-text a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
.rich-text a:hover { color: var(--primary-dark); }
.rich-text img { max-width: 100%; height: auto; border-radius: var(--radius-sm); margin: 10px 0; }
.rich-text blockquote {
  margin: 14px 0;
  padding: 10px 16px;
  border-left: 3px solid var(--primary-line);
  background: var(--primary-soft);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--text-2);
}
.rich-text code {
  padding: 1px 6px;
  border-radius: 4px;
  background: #f1f4f4;
  font-family: ui-monospace, Consolas, monospace;
  font-size: var(--fs-xs);
}
.rich-text table { width: 100%; border-collapse: collapse; margin: 14px 0; font-size: var(--fs-base); }
.rich-text th, .rich-text td { border: 1px solid var(--border); padding: 8px 12px; text-align: left; }
.rich-text th { background: #f7f9f9; font-weight: 600; color: var(--text); }
.rich-text hr { border: 0; border-top: 1px solid var(--border); margin: 22px 0; }

/* ------------------------------ 表单 / 登录注册 ------------------------------ */

.auth-wrap {
  max-width: 420px;
  margin: 48px auto;
}

.auth-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 34px 34px 30px;
  box-shadow: var(--shadow);
}

.auth-card h1 {
  margin: 0 0 6px;
  font-size: var(--fs-xl);
  font-weight: 600;
  text-align: center;
}

.auth-card .sub {
  margin: 0 0 26px;
  text-align: center;
  color: var(--text-3);
  font-size: var(--fs-base);
}

.field { margin-bottom: 16px; }

.field label {
  display: block;
  margin-bottom: 6px;
  font-size: var(--fs-base);
  color: var(--text-2);
  font-weight: 500;
}

.field input, .field select, .field textarea {
  width: 100%;
  height: 42px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  outline: none;
  background: #fbfcfc;
  color: var(--text);
  transition: all .16s;
}

.field textarea { height: auto; min-height: 96px; padding: 11px 14px; resize: vertical; line-height: 1.65; }

.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--primary);
  background: #fff;
  box-shadow: 0 0 0 3px rgba(14, 124, 102, .08);
}

.field .hint { margin-top: 5px; font-size: var(--fs-xs); color: var(--text-3); }
/* 验证码：输入框 + 图片横向排列，图片高度与输入框（42px）对齐 */
.captcha-row { display: flex; gap: 10px; align-items: center; }
.captcha-row input { flex: 1; min-width: 0; }
.captcha-img {
  flex-shrink: 0;
  height: 42px;
  width: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: #fff;
  cursor: pointer;
}
.captcha-img:hover { border-color: var(--primary); }

.auth-foot {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--border-2);
  text-align: center;
  font-size: var(--fs-base);
  color: var(--text-3);
}
.auth-foot a { color: var(--primary); font-weight: 500; }

/* ------------------------------ 用户中心 ------------------------------ */

/* 顶部分页 tabs：「我的资料」「下载记录」「我的收藏」三档，
   右侧小数字标计档让用户立刻知道「我下过 N 个 / 收藏 N 个」。 */
.user-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 4px;
  flex-wrap: wrap;
}
.user-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-base);
  color: var(--text-2);
  transition: background .15s, color .15s;
  white-space: nowrap;
}
.user-tab:hover { background: var(--primary-soft); color: var(--primary); }
.user-tab.is-on {
  background: var(--primary);
  color: #fff;
  font-weight: 500;
}
.user-tab.is-on:hover { background: var(--primary-dark); color: #fff; }
.user-tab-cnt {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  background: rgba(255,255,255,.85);
  color: var(--primary);
  font-size: var(--fs-2xs);
  font-weight: 600;
}
.user-tab:not(.is-on) .user-tab-cnt {
  background: var(--primary-soft);
  color: var(--primary);
}

.user-hero {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px 28px;
  margin-bottom: 18px;
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

.user-hero .big-avatar {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: var(--fs-2xl);
  font-weight: 600;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.user-hero .uinfo { flex: 1; min-width: 180px; }
.user-hero .uinfo h1 { margin: 0 0 4px; font-size: var(--fs-xl); font-weight: 600; }
.user-hero .uinfo .sub { font-size: var(--fs-sm); color: var(--text-3); }

.level-pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 11px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: #fff;
  vertical-align: middle;
  margin-left: 8px;
}

/* 签到环卡片：左侧 SVG 圆环 + 中央 +N/✓，右侧 7 天历史点 + 连续天数。
   视觉上像一个目标进度条，引导用户维持每日签到 */
.signin-ring-card {
  display: flex;
  align-items: center;
  gap: 22px;
  background: linear-gradient(135deg, #fff, rgba(var(--primary-rgb), .04));
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 18px 22px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}
.signin-ring {
  position: relative;
  width: 86px;
  height: 86px;
  flex: 0 0 86px;
}
.signin-ring svg { transform: rotate(-90deg); display: block; }
.signin-ring .ring-bg {
  fill: none;
  stroke: var(--border-2);
  stroke-width: 8;
}
.signin-ring .ring-fg {
  fill: none;
  stroke: var(--primary);
  stroke-width: 8;
  stroke-linecap: round;
  transition: stroke-dasharray .35s ease;
}
.signin-ring .ring-fg.is-done {
  stroke: var(--primary-dark);
}
.signin-ring-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1.1;
}
.signin-ring-center .ring-check {
  font-size: var(--fs-3xl);
  color: var(--primary-dark);
  font-weight: 700;
  margin-bottom: 2px;
}
.signin-ring-center .ring-plus {
  font-size: var(--fs-2xl);
  color: var(--primary);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.signin-ring-center .ring-cap {
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.signin-meta {
  flex: 1;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.signin-streak {
  font-size: var(--fs-base);
  color: var(--text);
}
.signin-streak b {
  color: var(--primary-dark);
  font-size: var(--fs-lg);
  font-variant-numeric: tabular-nums;
  margin: 0 2px;
}
.signin-badge {
  display: inline-block;
  margin-left: 8px;
  padding: 2px 8px;
  font-size: var(--fs-xs);
  font-weight: 600;
  border-radius: 10px;
  background: linear-gradient(90deg, #f6c453, #e88a3a);
  color: #fff;
  vertical-align: middle;
}
.signin-hint {
  margin-left: 10px;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.signin-strip {
  display: flex;
  gap: 8px;
  align-items: center;
}
.signin-dot {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  border: 1.5px solid var(--border-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: transparent;
  transition: all .15s;
}
.signin-dot.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.signin-form { margin-top: 2px; }


.stat-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
  margin-bottom: 18px;
}

.stat-box {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
}
.stat-box .k { font-size: var(--fs-xs); color: var(--text-3); margin-bottom: 6px; }
.stat-box .v { font-size: var(--fs-2xl); font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
.stat-box .v small { font-size: var(--fs-sm); font-weight: 500; color: var(--text-3); margin-left: 3px; }

.progress-line {
  height: 7px;
  border-radius: 4px;
  background: var(--border-2);
  overflow: hidden;
  margin-top: 8px;
}
.progress-line i {
  display: block;
  height: 100%;
  background: var(--primary);
  border-radius: 4px;
  transition: width .4s;
}

/* ------------------------------ 表格 ------------------------------ */

.table-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}

table.tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
table.tbl th {
  text-align: left;
  padding: 12px 16px;
  background: #fafbfb;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  color: var(--text-2);
  font-size: var(--fs-sm);
  white-space: nowrap;
}
table.tbl td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-2);
  vertical-align: middle;
}
table.tbl tr:last-child td { border-bottom: 0; }
table.tbl tbody tr:hover { background: #fafcfb; }

/* 短列不折行 / 定宽（2026-10-16）
   ⚠️ .nowrap 这个类一直写在模板里，但 style.css 里**从来没有定义过** ——
      前台 4 张表格（help / user-downloads / user-upload / user）的
      「消耗积分 / 下载时间 / 状态 / 操作」等短列因此会折行
      （实测 820px 下「2026-10-15 17:03」被折成两行）。这里补上定义。
   ⚠️ colw-4 口径与后台一致：box-sizing:border-box，
      列宽 = 字数 × 字号 + 左右 padding(16+16=32)。4 个汉字 = 4×14+32 = 88px。
   ⚠️ 三个属性缺一不可（同后台 2026-10-15 的结论）：只有 width 会被压到表头最小宽度，
      只有 width+max-width 会被长内容顶开；必须 width + min-width + max-width。 */
table.tbl .nowrap { white-space: nowrap; }
table.tbl .colw-4 { width: 88px; min-width: 88px; max-width: 88px; }

/* 窄屏：表格放不下时允许横滑（2026-10-16）
   ⚠️ .table-card 是 overflow:hidden（为了圆角裁剪）。表格比容器宽时，
      右侧的列会被**直接切掉**，而且滑不动 —— 实测 390px 手机上「我的下载」
      表格 792px、容器 360px，右侧「栏目 / 消耗积分 / 下载时间 / 操作」四列全部看不见，
      用户只能看到「资料名称」。这不是新问题，但栏目列定宽后溢出更明显，必须一起修。
   ⚠️ 桌面端表格本来就放得下（≤1280px 时表宽 = 容器宽），这条不生效。 */
@media (max-width: 860px) {
  .table-card { overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ------------------------------ 页脚 ------------------------------ */

.site-footer {
  background: #fff;
  border-top: 1px solid var(--border);
  margin-top: 0;
  padding: 20px 0 26px;
}

.footer-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr 1fr 1.2fr;
  gap: 36px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--border-2);
}

.footer-col h4 {
  margin: 0 0 14px;
  font-size: var(--fs-base);
  font-weight: 600;
}

.footer-col p {
  margin: 0 0 10px;
  font-size: var(--fs-sm);
  color: var(--text-2);
  line-height: 1.75;
}

.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 9px; }
.footer-col li a { font-size: var(--fs-sm); color: var(--text-2); }
.footer-col li a:hover { color: var(--primary); }

.footer-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: var(--fs-md);
  font-weight: 700;
  margin-bottom: 12px;
}

.footer-bottom {
  padding-top: 22px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  font-size: var(--fs-xs);
  color: var(--text-3);
}
.footer-bottom .links { display: flex; gap: 18px; flex-wrap: wrap; }

/* ---- 页脚统计图标（2026-10-14）-------------------------------------------
   页脚底栏右侧的一枚小徽标（柱状图图标 + 「网站统计」），点击跳到统计平台。
   由后台「系统配置 → 网站统计 → 页脚显示统计图标」控制，默认关。
   ⚠️ 文字色用 --text-3 在这里是安全的：底色是纯白（.site-footer background:#fff），
      白底上 --text-3 对比度 4.76:1 达标。若哪天把页脚底色改掉，这里要换 --text-2。 */
.footer-stat { display: flex; align-items: center; gap: 10px; }
/* 管理员粘官方图标代码时，兜一下基线对齐 —— 不然 <img> 会跟文字对不齐 */
.footer-stat img { vertical-align: middle; }
.stat-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px 3px 8px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--text-3);
  font-size: var(--fs-xs);
  line-height: 1.5;
  white-space: nowrap;
  transition: color .15s, border-color .15s;
}
.stat-badge:hover { color: var(--primary); border-color: var(--primary); }
.stat-badge svg { flex: 0 0 auto; }

/* ---- 页脚导航（2026-10-12）------------------------------------------------
   页脚精简为 5 个入口：关于我们 / 帮助中心 / 网站地图 / 意见建议 / 联系我们。
   联系方式与二维码已集中到 /contact 页，页脚不再渲染（原来的 .footer-grid /
   .footer-brand / .fc-* 规则保留未删，回滚时无需一并还原）。 */
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 28px;
  padding-bottom: 28px;
  border-bottom: 1px solid var(--border-2);
}
.footer-nav a {
  font-size: var(--fs-base);
  color: var(--text-2);
}
.footer-nav a:hover { color: var(--primary); }

/* ---- 联系我们页（2026-10-12）--------------------------------------------- */
.contact-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
}
.contact-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px 16px;
  text-align: center;
  background: #fff;
}
.contact-card .cc-name {
  font-size: var(--fs-base);
  font-weight: 600;
  margin-bottom: 8px;
}
.contact-card .cc-value {
  font-size: var(--fs-sm);
  color: var(--text-2);
  margin-bottom: 12px;
  word-break: break-all;
}
.contact-card .cc-qr {
  display: block;
  width: 150px;
  height: 150px;
  margin: 0 auto;
  object-fit: contain;
  border: 1px solid var(--border-2);
  border-radius: 8px;
  background: #fff;
}
.contact-card .cc-tip {
  margin-top: 8px;
  font-size: var(--fs-xs);
  color: var(--text-2);
}

/* ---- 页脚 QQ / 微信（2026-10-11）------------------------------------------
   条目来自后台「系统配置 → 联系方式」，渲染在页脚第 4 列。
   ⚠️ 二维码弹层向上弹（bottom:100%）—— 页脚在最底部，向下弹会跑到屏幕外。
   ⚠️ 默认 display:none 是**期望状态**，不是「少一条 CSS 就变空白」那类元素：
      即使样式表整块没加载，最坏也只是二维码一直显示，信息不会丢。
   ⚠️ 桌面靠 :hover，手机没有 hover（且 :hover 在触屏上会「粘住」），
      所以 main.js 里另有点击切换 .is-open —— 两套入口都要留。 */
.footer-contacts li {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}
.fc-label { color: var(--text-3); font-size: var(--fs-sm); flex: none; }
.fc-label::after { content: '：'; }
.fc-value { color: var(--text-2); font-size: var(--fs-sm); word-break: break-all; }

.fc-item { position: relative; }
.fc-has-qr { cursor: pointer; }
.fc-has-qr .fc-label,
.fc-has-qr .fc-value { border-bottom: 1px dashed var(--primary-line, #cfe6e0); }

.fc-qr {
  position: absolute;
  left: 0;
  bottom: 100%;
  margin-bottom: 8px;
  display: none;
  z-index: 60;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
  text-align: center;
}
.fc-qr img {
  display: block;
  width: 124px;
  height: 124px;
  object-fit: contain;
  border-radius: 6px;
}
.fc-qr i {
  display: block;
  margin-top: 4px;
  font-style: normal;
  font-size: var(--fs-xs);
  color: var(--text-3);
}

/* 桌面悬停即弹出；键盘 Tab 也能触发（:focus-within）；手机端靠 .is-open。 */
.fc-has-qr:hover > .fc-qr,
.fc-has-qr:focus-within > .fc-qr,
.fc-has-qr.is-open > .fc-qr { display: block; }

/* 窄屏：页脚变 1~2 列，弹层贴左边界即可，不会溢出（列宽 = 屏宽）。 */
@media (max-width: 640px) {
  .fc-qr img { width: 104px; height: 104px; }
}

/* ------------------------------ 杂项 ------------------------------ */

.center-box {
  max-width: 480px;
  margin: 80px auto;
  text-align: center;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 56px 40px;
}
.center-box h1 { font-size: var(--fs-display); margin: 0 0 10px; color: var(--primary); font-weight: 700; }
.center-box p { color: var(--text-2); margin: 0 0 24px; }

/* ------------------------------ 响应式 ------------------------------ */

@media (max-width: 1024px) {
  .detail-layout { grid-template-columns: minmax(0, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 26px; }
}

@media (max-width: 860px) {
  .section-grid { grid-template-columns: minmax(0, 1fr); }
  /* 顶栏两行布局（logo+登录/注册 / 导航）已在基础规则里统一实现，
     这里只做窄屏的尺寸收缩，不再重复 order/flex。 */
  .header-top { padding: 10px 0; gap: 8px 14px; }
  .logo { font-size: var(--fs-lg); }
  .logo-img { height: 30px; }
  .logo-mark { width: 30px; height: 30px; font-size: var(--fs-md); }
  /* 窄屏恢复旧行为：搜索框紧跟 logo，操作区自己顶到右边
     （宽屏时是搜索框的 auto 外边距在顶，见 .header-search）。 */
  .header-search { margin-left: 0; }
  .header-actions { min-height: 0; margin-left: auto; }
  .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero { padding: 28px 20px; }
  .hero h1 { font-size: var(--fs-2xl); }
  .hero-stats { gap: 28px; }
  .detail-card { padding: 22px 20px; }
  .row-item { padding: 15px 16px; gap: 12px; }
  .row-icon { width: 40px; height: 40px; font-size: var(--fs-2xs); }

  /* 轮换框条目：窄屏改为上下两行。
     桌面端 .res-title 是 flex:1 + min-width:0、.res-meta 是 flex-shrink:0，
     窄屏时元信息会把标题挤成 0 宽（标题直接消失），这里必须拆成块级两行。 */
  .tab-section .res-item {
    align-items: flex-start;
    padding: 11px 14px;
  }
  .tab-section .res-body { display: block; }
  .tab-section .res-title { display: block; flex: none; }
  .tab-section .res-meta {
    margin-top: 5px;
    flex-wrap: wrap;
    gap: 4px 14px;
    font-size: var(--fs-xs);
  }
}

/* ↓ 以下 @media (max-width: 560px) 由 4 处分散的块合并而来（2026-10-07 断点收敛）。
   合并位置刻意选在**原最后一块**处 —— 保证各断点之间的相对先后不变。 */
@media (max-width: 560px) {
  .related-cols { grid-template-columns: minmax(0, 1fr); gap: 0; }

  .tags-hot-card { padding: 14px 14px 16px; }
  .hot-tag.lv-3 { font-size: var(--fs-md); padding: 7px 12px; }
  .hot-tag.lv-2 { font-size: var(--fs-base); }

  .signin-ring-card { padding: 14px 16px; gap: 14px; }
  .signin-ring { flex-basis: 72px; width: 72px; height: 72px; }

  .wrap { padding: 0 14px; }
  .footer-grid { grid-template-columns: 1fr; }
  .hero-stats { gap: 20px; }
  .hero-stats .st b { font-size: var(--fs-lg); }
  .user-hero { padding: 20px; gap: 16px; }
  .auth-card { padding: 26px 22px; }
  .res-item { padding: 9px 14px; }
  .section-head { padding: 13px 14px; }
  .tab-section .section-head { padding: 6px 10px 0; }
  .tab-btn { padding: 8px 10px 11px; font-size: var(--fs-base); }
  .tab-btn.active::after { left: 8px; right: 8px; }
  .detail-card h1 { font-size: var(--fs-lg); }

  /* 登录态顶栏：登录后操作区是「头像+昵称+积分 / 后台 / 退出」，比未登录的
     「登录 / 注册」宽一倍多。375px 下（.wrap 左右各 14px，可用 347px）
     logo 145px + 操作区 251px 放不下 → 操作区换行、导航被顶到第 3 行。
     窄屏收起昵称与积分（只留头像，移动端通用做法），按钮收紧，
     保证第一行仍然是 logo + 操作区。
     移动端 user-chip 加大内边距到 8px、确保最小 44x44 点击区
     （Apple HIG / Material 都要求触控目标 ≥44pt）。 */
  .user-chip { padding: 8px; gap: 0; min-width: 44px; min-height: 44px; justify-content: center; }
  .user-chip .u-text { display: none; }
  .header-actions { gap: 8px; }
  .header-actions .btn-sm { padding: 0 10px; }

  /* 375px + 线上真实站名「材料狗资源下载中心」(9 字) 的实测：
     登录态操作区 154px，17px 字号下 logo 198px，198+14+154=366 > 347（可用宽）
     → 操作区换行、导航被顶到第 3 行。
     关键点：flex-wrap 的换行判定用的是 flex **基准宽度**，不是压缩后的宽度，
     所以只给 .logo 设 flex-shrink:1 是没用的 —— 基准宽度放不下就照样换行。
     把 .logo 的基准宽度设为 0（flex:1 1 0），第一行永远放得下（0+14+154），
     再由 logo 自适应伸缩：名字再长也只是走省略号，不会把操作区挤下去。
     字号同步降到 15px，让 9 字全名在 375px 下能完整显示。 */
  .logo { font-size: var(--fs-md); flex: 1 1 0; }
}

/* 反馈页类别 chip：图标 + 标签的胶囊样式，比单选按钮更醒目 */
.fb-kinds {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}
.fb-kind {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1.5px solid var(--border);
  border-radius: 22px;
  background: #fff;
  font-size: var(--fs-base);
  color: var(--text-2);
  cursor: pointer;
  transition: all .15s;
  user-select: none;
}
.fb-kind:hover {
  border-color: var(--primary-line);
  color: var(--primary);
}
.fb-kind input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  /* 2026-10-07 修：本元素是 <input type="radio">，被 .field input{width:100%} 命中；
     又因 position:absolute 且没有任何非 static 祖先，包含块退化成「初始包含块」
     （= 视口），于是每个隐形 radio 的宽度 = 视口宽度，把 /feedback 撑出横向滚动条。
     实测溢出：1920px → +994px、1440 → +754、1366 → +717、1024 → +546。
     （手机端被浏览器自动缩放掩盖，看着是「零溢出」，实际一样坏。）
     只补这两个尺寸即可 —— radio 本身 opacity:0 + pointer-events:none，
     视觉零变化；label 点击照常选中（改后实测 checked 状态正确）。 */
  width: auto;
  height: auto;
}
.fb-kind-ic {
  display: inline-flex;
  width: 16px;
  height: 16px;
  color: var(--text-3);
}
.fb-kind-ic svg { width: 16px; height: 16px; }
.fb-kind:hover .fb-kind-ic { color: var(--primary); }
.fb-kind.is-on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  box-shadow: 0 2px 6px rgba(var(--primary-rgb), .25);
}
.fb-kind.is-on .fb-kind-ic { color: #fff; }
.fb-context {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
  padding: 6px 12px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: var(--fs-xs);
  border-radius: 4px;
}
.fb-context b { font-weight: 600; }

/* ==========================================================================
   列表 / 表格里的「标题」：单行显示，超出容器宽度用省略号；
   完整标题由元素自身的 title="…" 属性在鼠标悬停时显示（模板里已同步加上）。
   ⚠️ 三件事必须同时成立，少一件省略号就不出现：
     ① 容器真的比文本窄 —— 栅格列写 minmax(0, 1fr)，flex 子项写 min-width: 0；
     ② 被截断的元素是块级（display: block）且 overflow: hidden；
     ③ 配 white-space: nowrap + text-overflow: ellipsis。
   （实测：给 <td> 直接加 text-overflow 不可靠，必须落在内层块级元素上。）
   ========================================================================== */

/* /list、/search 的列表行标题 */
.row-title a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 首页公告条的标题（本身就是 flex 子项，已有 flex:1 + min-width:0） */
.announce-item .an-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* 详情页侧栏「本栏目更多」的条目文字（跳过序号 .idx） */
.side-list li a > span:not(.idx) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }

/* /user、/user/downloads 的「资料名称」列 */
table.tbl .t-title { max-width: 380px; }
table.tbl .t-title > a,
table.tbl .t-title > span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ===== mobile-fix 2026-10-07 ===== */
/* 本轮「手机适配」修复，全部限制在 @media ≤860px 内 ——
   桌面（≥1024px）读不到这些规则。已用 DOM 逐元素快照实测确认桌面零变化
   （1440px 下 diff = 0 条；把同样内容不包媒体查询裸写则产生 470 条差异，
   证明探针本身是有效的）。
   ⚠️ 必须放在文件末尾：要覆盖前面 @media ≤860px 里 .main-nav 的
      overflow-x:visible，以及 @media ≤640px 里 .hero-search-btn 的 32×32。 */

/* 汉堡按钮：桌面完全隐藏 —— display:none 既不占位、也不进无障碍树，
   桌面布局与改动前逐像素一致。 */
.nav-toggle { display: none; }

@media (max-width: 860px) {

  /* ② 触控目标 ≥44px（Apple HIG / Material 都要求）。
     改前实测：顶栏搜索按钮 28×28、hero 搜索按钮 32×32、logo 34×30。 */
  .nav-toggle {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: #fff;
    cursor: pointer;
    flex-shrink: 0;
  }
  /* 横线的可见属性（宽/高/圆角/底色）写在 header.ejs 的内联 style 上 ——
     样式表缺失时图标仍可见。这里只负责过渡与展开态动画。 */
  .nav-toggle-bar { transition: transform .18s, opacity .18s; }
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(2) { opacity: 0; }
  .nav-toggle[aria-expanded="true"] .nav-toggle-bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

  /* ③ 窄屏导航折叠。改前是「换行平铺」：9 个栏目占 3 行共 122px，
     390px 下页头总高 227px（视口 844px 的 27%）且 position:sticky 永久吸顶。
     收起后页头约 105px；点汉堡展开后仍是原来的换行平铺样子，只是不再常驻。 */
  .main-nav { display: none; }
  .main-nav.is-open { display: flex; }

  .header-search input { height: 44px; padding-right: 46px; }
  .header-search button[type="submit"] { width: 40px; height: 40px; right: 2px; }
  .hero-search-btn { width: 40px; height: 40px; right: 3px; }
  .logo { min-height: 44px; }

  /* ④ .row-icon 桌面本来就是 12px，只有窄屏被压到 11px
     （列表页 51 处 / 栏目页 65 处）—— 统一回 12px，桌面不受影响。 */
  .row-icon { font-size: var(--fs-xs); }

  /* ⑤ iOS Safari 聚焦 font-size < 16px 的输入框时会自动放大整页且不缩回。
     改前实测：顶栏搜索框 13.5px（全站每页）、首页搜索框 14px、表单控件 14px。
     ⚠️ 必须显式列出 .header-search input / .hero-search input —— 它们的选择器
        特异性是 (0,1,1)，只写 input 元素选择器 (0,0,1) 压不住。
        （.field input 系列没有 font-size 声明，所以会被下面这条直接覆盖，无需列出。） */
  input, select, textarea,
  .header-search input, .hero-search input { font-size: var(--fs-md); }

  /* ⑥ 轮动框 tab 换短标签。改前 4 个 4 字标题在 360/390px 放不下 ——
     实测 tab-nav 换行成 2 行（高 79.2px），「免费下载」掉到第二行，
     右侧「更多」被挤成竖排「更 / 多」两行。短标签后 4 个 tab 合计约 198px，
     360px 也能单行放下（可用宽 273.8px）。
     桌面端 .tab-label-short 恒为 display:none，一个字都不变。 */
  .tab-label-full { display: none; }
  .tab-label-short { display: inline; }
}

/* ==========================================================================
   扫码支付页（/pay/:id）
   ========================================================================== */

.btn-pay {
  background: #d97706;
  color: #fff;
}
.btn-pay:hover { background: #b45309; color: #fff; }

.pay-head { margin-bottom: 20px; }
.pay-back {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-sm);
  color: var(--text-3);
  text-decoration: none;
  margin-bottom: 10px;
}
.pay-back:hover { color: var(--primary); }
.pay-head h1 {
  font-size: var(--fs-2xl);
  margin: 0 0 6px;
  letter-spacing: -.3px;
}
.pay-sub {
  margin: 0;
  font-size: var(--fs-base);
  color: var(--text-2);
}

.pay-layout {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: 20px;
  align-items: start;
}

.pay-qr-card,
.pay-info-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.pay-qr-card { padding: 24px 20px; text-align: center; }

.pay-amount {
  margin-bottom: 16px;
  color: #b45309;
  line-height: 1;
}
.pay-amount .cur { font-size: var(--fs-xl); font-weight: 600; margin-right: 2px; }
.pay-amount .num { font-size: var(--fs-display); font-weight: 700; letter-spacing: -1px; }

.pay-qr-box {
  width: 260px;
  height: 260px;
  margin: 0 auto 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.pay-qr-box svg { display: block; width: 100%; height: 100%; }
.pay-qr-img { width: 100%; height: 100%; object-fit: contain; }
.pay-qr-empty { color: var(--text-3); text-align: center; }
.pay-qr-empty p { margin: 8px 0 0; font-size: var(--fs-sm); }

.pay-channel {
  font-size: var(--fs-xs);
  color: var(--text-2);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}
.pay-badge {
  font-size: var(--fs-xs);
  padding: 2px 7px;
  border-radius: 20px;
  font-weight: 600;
}
.pay-badge.auto { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
.pay-badge.manual { background: #fffbeb; color: #b45309; border: 1px solid #fde68a; }

.pay-hint {
  margin: 14px 0 0;
  font-size: var(--fs-sm);
  color: var(--text-2);
  line-height: 1.7;
}

.pay-manual-tip {
  margin-top: 16px;
  padding: 14px;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: var(--radius-sm);
  font-size: var(--fs-sm);
  color: #92400e;
  text-align: left;
  line-height: 1.75;
}
.pay-note-code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-2xl);
  font-weight: 700;
  letter-spacing: 4px;
  text-align: center;
  color: #b45309;
  background: #fff;
  border: 1px dashed #fcd34d;
  border-radius: var(--radius-sm);
  padding: 8px 0;
}

.pay-raw { margin-top: 14px; text-align: left; font-size: var(--fs-xs); color: var(--text-3); }
.pay-raw summary { cursor: pointer; }
.pay-raw textarea {
  width: 100%;
  margin-top: 8px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-xs);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 8px;
  resize: vertical;
  color: var(--text-2);
  word-break: break-all;
}

.pay-info-card { padding: 20px; }
.pay-info-card h3 {
  font-size: var(--fs-md);
  margin: 0 0 14px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-2);
}

.pay-dl {
  margin: 0 0 18px;
  display: grid;
  grid-template-columns: 74px 1fr;
  gap: 9px 12px;
  font-size: var(--fs-base);
}
.pay-dl dt { color: var(--text-3); }
.pay-dl dd { margin: 0; color: var(--text); word-break: break-all; }
.pay-dl dd.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs-xs);
}

.pay-status {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px;
  border-radius: var(--radius-sm);
  background: var(--primary-soft);
  border: 1px solid var(--primary-line);
  margin-bottom: 16px;
}
.pay-status-icon {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 38px;
}
.pay-status-icon.waiting { background: #fff; color: var(--primary); border: 1px solid var(--primary-line); }
.pay-status-icon.paid { background: #ecfdf5; color: #047857; border: 1px solid #a7f3d0; }
.pay-status-icon.closed { background: #fef2f2; color: #b91c1c; border: 1px solid #fecaca; }
.pay-status-title { font-size: var(--fs-base); font-weight: 600; }
.pay-status-sub { font-size: var(--fs-xs); color: var(--text-2); margin-top: 2px; }

.pay-warn {
  margin: 16px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--border-2);
  font-size: var(--fs-xs);
  color: var(--text-3);
  line-height: 1.75;
}
.pay-warn b { color: #b45309; }

@media (max-width: 860px) {
  .pay-layout { grid-template-columns: 1fr; }
  .pay-qr-box { width: 220px; height: 220px; }
  .pay-amount .num { font-size: var(--fs-3xl); }
}

/* ---- 支付方式切换（聚合通道：支付宝 / 微信） ----
   一个聚合商户号能同时收两家，用户自己挑。做成胶囊按钮组，
   当前选中的那个用主题色实心，一眼能看出「现在扫的是哪个码」。 */
.pay-types {
  display: flex;
  gap: 8px;
  margin: 12px 0 0;
}
.pay-type {
  flex: 1;
  text-align: center;
  padding: 9px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-2);
  text-decoration: none;
  background: #fff;
  transition: all .15s;
}
.pay-type:hover { border-color: var(--primary); color: var(--primary); }
.pay-type.on {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* ===================== 网站地图（2026-10-11）===================== */
.sitemap-page { padding-top: 28px; padding-bottom: 48px; }
.sitemap-page .page-title { font-size: var(--fs-2xl); font-weight: 700; margin-bottom: 6px; }
.sitemap-page .page-subtitle { color: var(--text-3); font-size: var(--fs-sm); margin-bottom: 24px; }
.sitemap-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}
@media (max-width: 860px) {
  .sitemap-grid { grid-template-columns: 1fr; gap: 18px; }
}
.sitemap-block { background: #fff; border: 1px solid var(--border); border-radius: 10px; padding: 18px 20px; }
.sitemap-block-wide { grid-column: 1 / -1; }
.sitemap-block h2 { font-size: var(--fs-md); font-weight: 700; margin-bottom: 12px; color: var(--text-1); }
.sitemap-block ul { list-style: none; padding: 0; margin: 0; }
.sitemap-block ul li { margin-bottom: 8px; font-size: var(--fs-base); }
.sitemap-block ul li a { color: var(--text-2); text-decoration: none; }
.sitemap-block ul li a:hover { color: var(--primary); text-decoration: underline; }
.sitemap-contents { display: grid; grid-template-columns: repeat(2, 1fr); gap: 6px 24px; }
@media (max-width: 640px) {
  .sitemap-contents { grid-template-columns: 1fr; }
}
.sitemap-meta { color: var(--text-3); font-size: var(--fs-xs); margin-left: 6px; }

/* ===== A批：可访问性增强（2026-10-11） ===== */
/* 全站键盘焦点环：链接/按钮/摘要/分页/表单控件聚焦时可见 */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.tab-btn:focus-visible,
.pager a:focus-visible,
.nav-item:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* 跳到主内容：键盘用户绕过页头 */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
  padding: 10px 16px;
  background: var(--primary);
  color: #fff;
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.skip-link:focus { left: 8px; top: 8px; }

/* 尊重系统「减少动态效果」偏好 */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
