@charset "UTF-8";
/*
 * OneNav 子主题 - 自定义样式
 *
 * 加载顺序在父主题 main.css 之后，靠层叠 + 特异性覆盖。
 * 本文件只做「父主题缺失的能力补齐」，不做视觉重构。
 *
 * 每一节都标注了对应的实测证据，改动前先看证据还成不成立。
 */

/* =========================================================================
 * 1. 键盘焦点可见性
 *
 * 实测（线上首页）：抽查 6 个主要可聚焦元素
 *   .sites-body / .search-key / .togo /
 *   .switch-dark-mode / .aside-item a / .search-submit-btn
 * 结果 6/6 全部「无可见焦点环」—— 键盘用户完全看不到自己在哪。
 *
 * 父主题有 2 处 outline:none（main.css:7441 / 9511），
 * 且全库 :focus-visible 出现 0 次。
 *
 * 这里统一补一套 :focus-visible 焦点环。
 * 用 :focus-visible 而非 :focus，鼠标点击不会出现焦点环，
 * 只有键盘 Tab 导航才显示，不影响现有视觉。
 * ====================================================================== */

.io-sub-enhanced a:focus-visible,
.io-sub-enhanced button:focus-visible,
.io-sub-enhanced input:focus-visible,
.io-sub-enhanced select:focus-visible,
.io-sub-enhanced textarea:focus-visible,
.io-sub-enhanced [tabindex]:focus-visible,
.io-sub-enhanced [role="button"]:focus-visible {
  outline: 2px solid var(--focus-color, var(--theme-color));
  outline-offset: 2px;
  border-radius: var(--theme-border-radius-xs, 4px);
}

/* 卡片本体：外扩焦点环容易被相邻卡片裁掉，改用内嵌描边 */
.io-sub-enhanced .sites-body:focus-visible,
.io-sub-enhanced .posts-item a:focus-visible {
  outline: 2px solid var(--focus-color, var(--theme-color));
  outline-offset: -2px;
}

/* 深色背景卡片（big 模式）上的焦点环需要更高对比 */
.io-sub-enhanced .big-posts .sites-body:focus-visible,
.io-sub-enhanced .big-meta a:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -3px;
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.45);
}

/* 搜索框获得焦点时给个明确的边框反馈 */
.io-sub-enhanced .search-key:focus-visible {
  outline: 2px solid var(--focus-color, var(--theme-color));
  outline-offset: -2px;
}

/* 跳转到主内容：键盘用户可以跳过 269 张卡片的导航区 */
.io-sub-skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100000;
  padding: 10px 18px;
  background: var(--main-bg-color, #fff);
  color: var(--theme-color);
  border-radius: var(--theme-border-radius-sm, 6px);
  box-shadow: 0 4px 16px var(--main-shadow, rgba(0, 0, 0, 0.15));
  font-size: 14px;
}
.io-sub-skip-link:focus {
  left: 12px;
  top: 12px;
}


/* =========================================================================
 * 2. 触控目标尺寸
 *
 * 实测：.togo（卡片右侧「直达」按钮）渲染尺寸 16×24px。
 * WCAG 2.5.8 要求最小 24×24，2.5.5（AAA）建议 44×44。
 * 移动端 16px 宽的点击区几乎必然误触。
 *
 * 用伪元素扩大热区，不改变视觉尺寸和布局。
 * ====================================================================== */

@media (pointer: coarse) {
  .io-sub-enhanced .togo,
  .io-sub-enhanced .icon-btn,
  .io-sub-enhanced .btn-tools {
    position: relative;
  }

  .io-sub-enhanced .togo::after,
  .io-sub-enhanced .icon-btn::after,
  .io-sub-enhanced .btn-tools::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    transform: translate(-50%, -50%);
    /* 只扩热区，不显示任何东西 */
  }

  /* tabbar 每一项保证 48px 高 */
  .io-sub-enhanced .tabbar-item {
    min-height: 48px;
  }
}


/* =========================================================================
 * 3. 动效降级（prefers-reduced-motion）
 *
 * 实测：父主题自身 CSS 有 196 处 transition + 29 处 animation，
 * 但 prefers-reduced-motion 规则数为 0（页面上检测到的 18 条来自 Bootstrap，
 * 覆盖不到主题自己的动画）。
 *
 * 前庭功能障碍用户开启「减弱动态效果」后，本主题依然全量播放动画。
 * ====================================================================== */

@media (prefers-reduced-motion: reduce) {
  .io-sub-enhanced *,
  .io-sub-enhanced *::before,
  .io-sub-enhanced *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  /* 轮播自动播放对这类用户尤其困扰，直接停掉动画 */
  .io-sub-enhanced .swiper-wrapper {
    transition-duration: 0.001ms !important;
  }

  /* 加载动画保留一点点，否则用户不知道在加载 */
  .io-sub-enhanced .icon-spin {
    animation-duration: 1.2s !important;
    animation-iteration-count: infinite !important;
  }
}


/* =========================================================================
 * 4. 触屏 hover 粘滞
 *
 * 实测：父主题 @media (hover: hover) 出现 0 次。
 * 触屏上点过的卡片会保持 hover 态，直到点别处才消失。
 *
 * 把 hover 效果限定在真正支持悬停的设备上。
 * ====================================================================== */

@media (hover: none) {
  .io-sub-enhanced .posts-item:hover,
  .io-sub-enhanced .sites-item:hover {
    transform: none;
    box-shadow: none;
  }
}


/* =========================================================================
 * 5. 提示条（showAlert）无障碍
 *
 * 实测：页面 aria-live / role=alert 区域数量为 0，
 * 屏幕阅读器读不到任何操作反馈（复制成功、点赞、提交结果等）。
 *
 * sub-app.js 会给 #alert_placeholder 加 role/aria-live，
 * 这里只保证它在视觉上不会挡住焦点元素。
 * ====================================================================== */

.io-sub-enhanced #alert_placeholder {
  pointer-events: none;
}
.io-sub-enhanced #alert_placeholder .alert-body {
  pointer-events: auto;
}


/* =========================================================================
 * 6. 图片宽高比占位
 *
 * 实测：732 张图片中 730 张没有 aspect-ratio；
 * 父主题输出的是 width="auto" height="auto"（非法值，浏览器忽略）。
 *
 * 当前实测 CLS 仅 0.0265（良好），所以这里只做温和加固，
 * 给懒加载占位图一个稳定比例，避免弱网下抖动。
 * ====================================================================== */

.io-sub-enhanced .sites-icon,
.io-sub-enhanced .item-image > img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.io-sub-enhanced .big-bg-cover {
  aspect-ratio: 16 / 9;
  object-fit: cover;
}


/* =========================================================================
 * 7. 搜索联想下拉：加载态与空态
 *
 * 父主题在请求期间保持旧内容、无结果时直接收起，
 * 用户不知道「在加载」还是「没结果」。
 * sub-app.js 会插入这两个状态节点。
 * ====================================================================== */

.io-sub-tips-state {
  padding: 14px 16px;
  color: var(--muted-color, #93959a);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.io-sub-tips-state .iconfont {
  font-size: 14px;
}


/* =========================================================================
 * 8. 网址卡片改版（style-sites-big）
 *
 * 目标形态：
 *   ┌─────────────────────┐
 *   │   首图 16:9 圆角     │
 *   ├─────────────────────┤
 *   │ [32] 名称（最多2行）  │
 *   │ 摘要最多两行，超出截断 │
 *   └─────────────────────┘
 *
 * 父主题原设计（main.css:6245-6360）是「120% 竖图 + 悬停上滑毛玻璃面板」，
 * 且 .big-meta 带 will-change:backdrop-filter —— 229 张卡就是 229 个
 * 独立 GPU 合成层，开销很大。新样式不需要毛玻璃，一并去掉。
 *
 * ── 两个必须知道的坑（v1.3.0 踩过）──────────────────────────────
 *
 * 坑 1：.item-body 的 class 是 "item-body overflow-hidden d-flex flex-column flex-fill"
 *       Bootstrap 的 .d-flex 是 `display:flex !important`，
 *       所以这里的 display:contents 必须加 !important 才能生效，
 *       否则 h3 和摘要不会成为 grid 项，布局会散掉。
 *
 * 坑 2：h3 的 class 是 "item-title line1" —— **标题自己也带 line1**。
 *       所以摘要不能用 .line1 选，必须用 .line1:not(.item-title)，
 *       否则标题会被当成摘要塞进 sum 区域。
 *
 * 坑 3：父主题 main.css 里 `.line1 { overflow:hidden; text-overflow:ellipsis;
 *       white-space:nowrap }` —— 这是个单行截断工具类，而标题和摘要都带着它。
 *       nowrap 会让 -webkit-line-clamp 永远只出一行，所以必须
 *       `white-space: normal !important` 解除。
 *       同时父主题把 .item-title 的 display 设成了 flow-root，
 *       所以 `display:-webkit-box` 也要 !important。
 *
 * 坑 4：移动端（≤767.98px）logo 整个消失 —— 父主题 main.css:6364 把
 *       `.row-col-2a .sites-item.style-sites-big .item-media` 设成了 display:none。
 *       这是**特异性**问题不是顺序问题，覆盖规则必须写全选择器链。
 *       详见本节末尾的移动端媒体查询。
 * ────────────────────────────────────────────────────────────
 * ====================================================================== */

/* --- 尺寸变量，改这里就能整体调 --- */
.io-sub-enhanced .style-sites-big {
  --card-logo-size: 32px;      /* 站点 logo 边长 */
  --card-title-lines: 2;       /* 标题最多几行 */
  --card-summary-lines: 2;     /* 摘要最多几行 */
  --card-title-size: 16px;
  --card-summary-size: 13px;
}

/* --- 卡片外壳 --- */
.io-sub-enhanced .style-sites-big.d-flex {
  display: flex !important;
  flex-direction: column;
  position: relative;               /* 供下方「整卡可点」的拉伸链接定位 */
  padding: 12px;
  background: var(--main-bg-color);
  border-radius: var(--theme-border-radius-xl);
  overflow: hidden;
}

.io-sub-enhanced .style-sites-big:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px -12px var(--main-shadow);
}

/* --- 首图：16:9，静态在顶部 --- */
.io-sub-enhanced .style-sites-big .big-bg {
  position: relative;
  padding-top: 56.25%;              /* 覆盖父主题的 120% */
  border-radius: var(--theme-border-radius-md);
  overflow: hidden;
  background: var(--muted-bg-color);
  flex: none;
}

.io-sub-enhanced .style-sites-big .big-bg .big-img {
  position: absolute;
  inset: 0;
}

.io-sub-enhanced .style-sites-big .big-bg .big-bg-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center top;
}

/* 倒影图已在 PHP 层删除，这里兜底 */
.io-sub-enhanced .style-sites-big .bg-reflect {
  display: none !important;
}

/* --- 信息区：从绝对定位浮层改成正常文档流 --- */
.io-sub-enhanced .style-sites-big .big-meta {
  position: static;
  width: auto;
  margin: 0;
  padding: 12px 2px 2px;
  bottom: auto;
  background: none;
  color: var(--main-color);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  will-change: auto;                /* 关键：撤掉 229 个合成层 */
  transition: none;
}

.io-sub-enhanced .style-sites-big:hover .big-meta {
  bottom: auto;
}

/* --- 布局：第一行 logo + 名称，第二行摘要独占 --- */
.io-sub-enhanced .style-sites-big .sites-body {
  display: grid;
  grid-template-columns: var(--card-logo-size) minmax(0, 1fr);
  grid-template-areas:
    "logo title"
    "sum  sum";
  /*
   * 最小高度给「第一行」而不是给标题本身 —— 这是标题单行时能和 logo 居中对齐的关键。
   *
   * 之前把 min-height 放在 .item-title 上，单行标题的文字会贴在 45px 高的框顶部，
   * 而 logo 是相对整个框居中的，于是看起来 logo 比标题低一截（实测偏差 11px）。
   * 试过 -webkit-box-pack:center 想让文字在框内居中 —— 对 -webkit-line-clamp 无效。
   *
   * 改成给行设最小高度后，align-items:center 会同时把 logo 和标题文字在行内居中，
   * 单行 / 双行标题都对齐（实测偏差 0），且卡片总高度保持一致（262px）。
   */
  grid-template-rows: minmax(calc(var(--card-title-size) * 1.4 * var(--card-title-lines)), auto) auto;
  align-items: center;
  column-gap: 10px;
  row-gap: 0;
}

/*
 * 整卡可点：首图在 <a class="sites-body"> 之外（父主题结构是
 * article > .big-bg + .big-meta > a.sites-body），所以点图片没反应。
 * 用拉伸伪元素把点击区扩到整张卡，点图片也能进详情页。
 * 卡片里已无其他可点元素（.togo / .sites-tags 都已隐藏），不会互相遮挡。
 */
.io-sub-enhanced .style-sites-big .sites-body::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

.io-sub-enhanced .style-sites-big .item-header {
  grid-area: logo;
  width: var(--card-logo-size);
  height: var(--card-logo-size);
}

/* 见上方「坑 1」：Bootstrap .d-flex 是 !important，这里必须也用 !important */
.io-sub-enhanced .style-sites-big .item-body {
  display: contents !important;
}

/* --- 名称：最多 2 行，超出截断 --- */
.io-sub-enhanced .style-sites-big .item-title,
.io-sub-enhanced .posts-item.style-sites-big .item-title {
  grid-area: title;
  margin: 0;
  font-size: var(--card-title-size);
  font-weight: 600;
  line-height: 1.4;
  color: var(--main-color);
  /* 见下方「坑 3」：必须 !important，父主题把 .item-title 设成了 display:flow-root */
  display: -webkit-box !important;
  -webkit-line-clamp: var(--card-title-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* 见下方「坑 3」：.line1 带 white-space:nowrap，不解除就永远只有一行 */
  white-space: normal !important;
  overflow-wrap: break-word;
}

.io-sub-enhanced .style-sites-big .item-title b {
  font-weight: 600;
}

/* --- 摘要：独占一行，最多 2 行，超出截断 ---
 * 见上方「坑 2」：必须排除 .item-title，因为 h3 自己也带 line1 */
.io-sub-enhanced .style-sites-big .sites-body .line1:not(.item-title) {
  grid-area: sum;
  margin-top: 10px;
  display: -webkit-box !important;
  -webkit-line-clamp: var(--card-summary-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal !important;
  font-size: var(--card-summary-size);
  line-height: 1.6;
  color: var(--muted-color);
  overflow-wrap: break-word;
  /* 固定占位，避免摘要长短不一导致卡片高度参差 */
  min-height: calc(var(--card-summary-size) * 1.6 * var(--card-summary-lines));
}

/* 标题不再自己撑高度 —— 交给上面的 grid-template-rows，否则单行标题会贴顶 */
.io-sub-enhanced .style-sites-big .item-title {
  min-height: 0;
}

/* --- logo 方块 32×32 --- */
.io-sub-enhanced .style-sites-big .item-media,
.io-sub-enhanced .posts-item.style-sites-big .item-image {
  width: var(--card-logo-size);
  height: var(--card-logo-size);
  min-width: var(--card-logo-size);
  border-radius: 8px;
  overflow: hidden;
  box-shadow: none;                 /* 去掉父主题的白色描边 */
}

.io-sub-enhanced .style-sites-big .sites-icon,
.io-sub-enhanced .posts-item.style-sites-big .fill-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* logo 背后的模糊底衬不再需要 */
.io-sub-enhanced .style-sites-big .blur-img-bg {
  display: none;
}

/* --- 精简：只留 首图 / Logo / 名称 / 摘要 --- */
.io-sub-enhanced .style-sites-big .meta-ico,
.io-sub-enhanced .style-sites-big .item-tags,
.io-sub-enhanced .style-sites-big .sites-tags,
.io-sub-enhanced .style-sites-big .big-togo {
  display: none;
}

/* --- 移动端 --- */
@media (max-width: 767.98px) {
  .io-sub-enhanced .style-sites-big {
    --card-title-size: 15px;
    --card-summary-size: 12px;
    --card-logo-size: 28px;
  }
  .io-sub-enhanced .style-sites-big.d-flex {
    padding: 10px;
  }

  /*
   * 坑 4：移动端 logo 消失
   *
   * 父主题 main.css:6364 有这么一条：
   *   @media screen and (max-width: 767.98px) {
   *     .row-col-2a .sites-item.style-sites-big .item-media,
   *     .row-col-2a .sites-item.style-sites-max .item-media { display: none; }
   *   }
   *
   * 这在父主题原设计里是合理的 —— 原来的 big 卡是「120% 竖图 + 悬停浮层」，
   * 移动端两列布局塞不下 logo。但新版卡片里 logo 是主要元素，必须恢复。
   *
   * ⚠️ 关键是特异性，不是加载顺序：
   *     父主题 .row-col-2a .sites-item.style-sites-big .item-media  → 4 个类 (0,4,0)
   *     子主题 .io-sub-enhanced .style-sites-big .item-media        → 3 个类 (0,3,0)
   *   子主题 CSS 虽然后加载，但特异性低，照样被压住。
   *   实测：3 个类的写法算出来仍是 display:none，5 个类才是 block。
   *
   * 所以这里必须写全父主题的选择器链再加 .io-sub-enhanced 前缀。
   *
   * 只恢复 style-sites-big（本子主题改版的卡型）；
   * style-sites-max 保持父主题原行为，不去动它。
   */
  .io-sub-enhanced .row-col-2a .sites-item.style-sites-big .item-media {
    display: block;
  }
}


/* =========================================================================
 * 9. 网址卡片：max 样式改为「Logo 在上 + 标题/简介在下，整体居中」
 *
 * ── 对应后台哪个配置 ─────────────────────────────────────────
 *
 * 后台：网址 → 网址分类 → 编辑某个分类 → 「文章卡片样式」
 * 五个选项从左到右依次是：
 *   ① 使用主题设置
 *   ② 圆形 + 两行 + 底部小标签  → style-sites-max   ← 本节改的就是这个
 *   ③ 圆形 + 一行              → style-sites-default
 *   ④ 小圆 + 一行              → style-sites-min
 *   ⑤ 大图 + 圆形 + 文字        → style-sites-big（第 8 节改的那个）
 *
 * 已实测确认：选了 ② 的分类，前台卡片 class 就是 style-sites-max
 * （尺寸 199×106，带 .sites-tags + .togo + 摘要，无首图）。
 *
 * ── 原结构 ───────────────────────────────────────────────────
 *
 * article.style-sites-max
 * ├── a.sites-body                 横向：logo 左，标题+摘要 右
 * │   ├── div.item-header          60×60 logo
 * │   └── div.item-body            h3.item-title + div.line1（摘要）
 * ├── div.meta-ico                 阅读/点赞数
 * └── div.sites-tags               分类标签 + a.togo（直达 ▷）
 *
 * ── 改成 ─────────────────────────────────────────────────────
 *
 *   ┌──────────────┐
 *   │    [logo]    │
 *   │     标题      │   ← 全部水平居中
 *   │   一句话简介   │
 *   └──────────────┘
 *
 * 按需求只保留 Logo / 标题 / 简介，隐藏 meta-ico 和 sites-tags。
 *
 * ⚠️ 影响范围：style-sites-max 不止用在分类模块，
 *    作者页「收藏 → 网址」也是用它渲染的（io-author.php:397
 *    `get_sites_card('max', $card_args)`）。两处会一起变成新样式。
 *
 * ⚠️ 坑 5（未完全查清）：移动端出现过「DeepSeek」被断成「DeepSe / ek」。
 *    已把 `word-break: break-word` 改成 `overflow-wrap: break-word`
 *    —— 后者是标准属性，只在单词本身放不下时才断，前者是等价于
 *    `overflow-wrap: anywhere` 的废弃别名，理论上更容易劈开单词。
 *
 *    但**这个改动没能验证有效**：在 104px 和 120px 宽的对照测试里，
 *    两种属性表现完全一致（都在放不下时断词）。
 *    真正的原因更可能是标题容器宽度没撑满 —— 实测 120px 宽的卡片里
 *    .item-body 只有 64px，而不是应有的 84px。
 *    受限于浏览器窗口缩不到 768px 以下，没能在真实移动视口复现定位。
 *
 *    如果装完还看到断词，需要在真机 DevTools 里量一下
 *    .item-body / .item-title 的计算宽度，才能继续往下查。
 *
 * ⚠️ 第 8 节的坑 3 在这里同样适用：标题和摘要都带父主题的 .line1
 *    （`white-space:nowrap` 单行截断工具类），所以两处都要
 *    `white-space: normal !important`；摘要选择器也必须
 *    `.line1:not(.item-title)`，否则会把标题一起选中。
 * ====================================================================== */

/* --- 尺寸变量，改这里就能整体调 --- */
.io-sub-enhanced .style-sites-max {
  --mx-logo: 56px;          /* logo 边长 */
  --mx-title: 15px;
  --mx-desc: 12.5px;
  --mx-title-lines: 2;      /* 标题最多几行 */
  --mx-desc-lines: 2;       /* 简介最多几行 */
}

/* --- 卡片外壳：竖向、内容居中 --- */
.io-sub-enhanced .style-sites-max {
  position: relative;                /* 供下方整卡可点的拉伸链接定位 */
  display: flex !important;
  flex-direction: column;
  padding: 20px 14px 18px;
  background: var(--main-bg-color);
  border-radius: var(--theme-border-radius-xl);
  text-align: center;
}

.io-sub-enhanced .style-sites-max:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 28px -12px var(--main-shadow);
}

/* --- 主体：logo 在上、文字在下 --- */
.io-sub-enhanced .style-sites-max .sites-body {
  display: flex !important;
  flex-direction: column;
  align-items: center;
  width: 100%;
  gap: 12px;
}

/* 整卡可点：卡片里已无其他可点元素（tags / togo 都隐藏了）。
 * 以后若恢复显示 togo，记得给它 position:relative; z-index:2 */
.io-sub-enhanced .style-sites-max .sites-body::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}

/* --- logo --- */
.io-sub-enhanced .style-sites-max .item-header {
  flex: none;
  width: var(--mx-logo);
  height: var(--mx-logo);
}

.io-sub-enhanced .style-sites-max .item-media,
.io-sub-enhanced .posts-item.style-sites-max .item-image {
  width: var(--mx-logo);
  height: var(--mx-logo);
  min-width: var(--mx-logo);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: none;               /* 去掉父主题的白色描边 */
}

.io-sub-enhanced .style-sites-max .sites-icon,
.io-sub-enhanced .posts-item.style-sites-max .fill-cover {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.io-sub-enhanced .style-sites-max .blur-img-bg {
  display: none;
}

/* --- 文字区 --- */
.io-sub-enhanced .style-sites-max .item-body {
  display: flex !important;
  flex-direction: column;
  align-items: center;
  width: 100%;
  overflow: visible !important;   /* 父主题有 overflow-hidden，会裁掉第二行 */
}

/* 标题：居中，最多 2 行。
 * min-height 固定住，否则标题 1 行的卡片简介会往上跑，一行里对不齐 */
.io-sub-enhanced .style-sites-max .item-title,
.io-sub-enhanced .posts-item.style-sites-max .item-title {
  margin: 0;
  width: 100%;
  text-align: center;
  font-size: var(--mx-title);
  font-weight: 600;
  line-height: 1.4;
  color: var(--main-color);
  display: -webkit-box !important;
  -webkit-line-clamp: var(--mx-title-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal !important;
  overflow-wrap: break-word;
  min-height: calc(var(--mx-title) * 1.4 * var(--mx-title-lines));
}

/* 简介：同样居中 + 固定高度，保证同一行的简介起点一致 */
.io-sub-enhanced .style-sites-max .sites-body .line1:not(.item-title) {
  margin: 6px 0 0;
  width: 100%;
  text-align: center;
  font-size: var(--mx-desc);
  line-height: 1.6;
  color: var(--muted-color);
  display: -webkit-box !important;
  -webkit-line-clamp: var(--mx-desc-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal !important;
  overflow-wrap: break-word;
  min-height: calc(var(--mx-desc) * 1.6 * var(--mx-desc-lines));
}

/* --- 精简：只留 Logo / 标题 / 简介 --- */
.io-sub-enhanced .style-sites-max .meta-ico,
.io-sub-enhanced .style-sites-max .sites-tags,
.io-sub-enhanced .style-sites-max .item-tags,
.io-sub-enhanced .style-sites-max .togo {
  display: none;
}

/* --- 移动端 --- */
@media (max-width: 767.98px) {
  .io-sub-enhanced .style-sites-max {
    --mx-logo: 48px;
    --mx-title: 14px;
    padding: 16px 10px 14px;
  }

  /*
   * 移动端隐藏简介。
   *
   * 移动端一行 2~3 列，卡片内宽只有 100px 出头，
   * 简介挤成好几行、又被截断，读不到完整信息，只是白占高度。
   * 移动端只留 logo + 名称，一屏能看到更多条目。
   *
   * 连 min-height 一起去掉，否则会留下一块空白。
   * 想在移动端也显示简介，把这条注释掉即可。
   */
  .io-sub-enhanced .style-sites-max .sites-body .line1:not(.item-title) {
    display: none !important;
    min-height: 0;
    margin: 0;
  }

  /* 简介没了，标题不用再固定两行高度，让卡片自然收紧 */
  .io-sub-enhanced .style-sites-max .item-title,
  .io-sub-enhanced .posts-item.style-sites-max .item-title {
    min-height: 0;
  }

  /* 与第 8 节坑 4 同理：父主题 main.css:6365 在移动端把
   * .row-col-2a .sites-item.style-sites-max .item-media 也设成了 display:none，
   * 必须写全选择器链才压得住（父主题 4 个类，这里 5 个） */
  .io-sub-enhanced .row-col-2a .sites-item.style-sites-max .item-media {
    display: block;
  }
}


/* =========================================================================
 * 10. 顶部导航宽度对齐内容区
 *
 * ── 问题 ─────────────────────────────────────────────────────
 *
 * 实测（视口 1400px）：
 *   顶部导航 .container-header ... 宽 1372px（max-width 1440）
 *   内容区   .ioui-content ....... 宽 1260px
 *   导航比内容左右各宽 56px，logo 和内容边缘对不齐。
 *
 * ── 原因：父主题是故意的 ──────────────────────────────────────
 *
 * main.css:3523
 *   .container-body:not(.full-container) .container-footer,
 *   .container-body:not(.full-container) .container-header {
 *     max-width: calc(var(--main-max-width) + 180px);
 *   }
 *
 * 后台「首页内容宽度」设的是 1260，+180 就是 1440 —— 数字对得上。
 *
 * ── 改法 ─────────────────────────────────────────────────────
 *
 * 去掉那个 +180，直接用 var(--main-max-width)。
 *
 * 好处是**跟随后台设置**：以后你在
 * 主题设置 → 基础 → 样式 → 「首页内容宽度 / 内容页宽度」改数值，
 * 导航会自动跟着变，不用回来改 CSS。
 *
 * 特异性：父主题 `.container-body:not(.full-container) .container-header`
 * 是 3 个类；`.io-sub-enhanced` 和 `.container-body` 都在 <body> 上，
 * 所以连写成 `.io-sub-enhanced.container-body` 就是 4 个类，压得住。
 *
 * 实测改后：导航与内容区 left / right 完全一致（66 / 1326）。
 * ====================================================================== */

.io-sub-enhanced.container-body:not(.full-container) .container-header {
  max-width: var(--main-max-width);
}

/*
 * ── v1.8.1 补充：光改 .container-header 不够 ──────────────────
 *
 * .container-header 只是导航的**内容层**。它外面还包着一层
 *   <header.main-header> > <div.header-nav.blur-bg> > <nav.container-header>
 *
 * .header-nav 才是那条**带灰色半透明背景的可见横条**
 * （background: rgba(245,245,245,0.75)），而它是 `max-width: none`，
 * 所以即使内容层收窄到 1240，背景条依然是 1372px —— 看上去「没生效」。
 *
 * 实测（视口 1400，--main-max-width: 1240）：
 *   nav.container-header ... 1240px（76 → 1316）← 上面那条规则已生效
 *   div.header-nav ......... 1372px（10 → 1382）← 背景条，没被约束
 *   .ioui-content .......... 1240px（76 → 1316）
 *
 * 所以背景条也要一起收窄并居中。加上之后三者完全对齐。
 *
 * 排查提示：以后觉得「导航宽度没变」，先在 DevTools 里确认你选中的
 * 到底是 .container-header 还是 .header-nav —— 两层尺寸不一样。
 */
.io-sub-enhanced .main-header .header-nav {
  max-width: var(--main-max-width);
  margin-left: auto;
  margin-right: auto;
}

/*
 * ── 页脚（v1.8.2 起一并对齐）─────────────────────────────────
 *
 * 父主题那条规则里 .container-footer 和 .container-header 是写在一起的，
 * 所以页脚原本也是 +180。
 *
 * 页脚的层级比导航简单，实测只有一层需要改：
 *   <footer.main-footer>                    max-width:none，背景透明
 *     └ <div.container-footer.container>    max-width: 1420px ← 就是它
 * 没有像 header 那样单独的背景层（.header-nav.blur-bg），
 * 两层背景都是 transparent，所以一条规则就够。
 *
 * 实测改后四个元素完全对齐（视口 1400，--main-max-width: 1240）：
 *   .header-nav ........ 1240px（76 → 1316）
 *   .container-header .. 1240px（76 → 1316）
 *   .container-footer .. 1240px（76 → 1316）
 *   .ioui-content ...... 1240px（76 → 1316）
 */
.io-sub-enhanced.container-body:not(.full-container) .container-footer {
  max-width: var(--main-max-width);
}


/* =========================================================================
 * 11. 网址卡片：default 样式改为「圆形 Logo + 标题同行，简介独占一行」
 *
 * ── 对应后台哪个配置 ─────────────────────────────────────────
 *
 * 后台：网址 → 网址分类 → 编辑某个分类 → 「文章卡片样式」
 *   ① 使用主题设置
 *   ② 圆形 + 两行 + 底部小标签  → style-sites-max      （第 9 节）
 *   ③ 圆形 + 一行              → style-sites-default  ← 本节改的就是这个
 *   ④ 小圆 + 一行              → style-sites-min      （未改）
 *   ⑤ 大图 + 圆形 + 文字        → style-sites-big      （第 8 节）
 *
 * ── 参考对象：https://hao.uisdc.com/ ──────────────────────────
 *
 * 实测抓的原站数值（.p-item .f-box，2026-08 版）：
 *   卡片   padding 14px / border-radius 10px / 背景 #fff / 静止无阴影
 *   hover  translateY(-4px) + 0 4px 20px rgba(0,0,0,.04)，标题变主题色
 *   Logo   28~32px，border-radius 100%，右外边距 5px，与标题同一行
 *   标题   16.4px / line-height 28px / 700，色 #3c3c3c，单行 overflow hidden
 *   简介   12px / line-height 18~20px，色 #8f8f8f，
 *          -webkit-line-clamp:2，固定高 36~40px
 *   成品卡片高度 104.5px
 *
 * 本节按同一套比例落到本站的变量体系上（颜色一律走主题变量，
 * 这样深色模式自动跟随，实测 io-black-mode 下卡片 #2D2E2F / 正文 #1B1D1F 正常）。
 * 实测成品高度 108.4px，与参考站基本一致。
 *
 * ── 原结构 ───────────────────────────────────────────────────
 *
 * article.style-sites-default              （padding:0，圆角 8px）
 * └ a.sites-body                           flex 横向，padding:10px
 *   ├ div.item-header > div.item-media     40px 圆形（父主题用 padding-bottom:100% 撑方）
 *   └ div.item-body.d-flex.flex-column
 *     ├ h3.item-title.line1                单行截断
 *     └ div.line1.text-muted.text-xs       单行截断 ← 摘要只能显示 8 个字左右
 * └ div.sites-tags > a.togo                悬停才出现的「直达」箭头，绝对定位右上角
 *
 * ── 改成 ─────────────────────────────────────────────────────
 *
 *   ┌────────────────────────┐
 *   │ (logo)  标题…           │  ← 两者垂直居中对齐
 *   │ 一句话简介，最多两行，   │  ← 通栏，宽度是原来的 1.4 倍
 *   │ 超出截断…               │
 *   └────────────────────────┘
 *
 * 用 CSS Grid 实现（和第 8 节 big 卡同一套思路）：
 *   grid-template-areas: "logo title"
 *                        "sum  sum"
 *
 * ── 影响范围（改之前先知道会动到哪些页面）───────────────────
 *
 *   1. 首页 / 分类页里「文章卡片样式」选了 ③ 的模块
 *   2. 主题设置里的全局默认如果是 ③，那所有没单独设置的模块都算
 *   3. 网址详情页底部的「相关推荐」—— io-tool.php:1025 把 'default'
 *      写死了：get_sites_card('default', array('class'=>'col-2a col-md-4a'))
 *      那里桌面端 4 列、卡片更宽，本节样式在那儿只会更宽松，不会出问题
 *   4. ajax 加载更多（ajax.php:184）走同一个 get_sites_card，样式一致
 *
 * ── 沿用前几节踩过的坑 ───────────────────────────────────────
 *
 * 坑 1（第 8 节）：.item-body 带 Bootstrap 的 .d-flex（display:flex !important），
 *        要让它的两个子元素直接参与外层 grid，必须
 *        `display: contents !important`，少了 !important 压不住。
 *
 * 坑 2（第 8 节）：h3 的 class 是 "item-title line1" —— 标题自己也带 .line1。
 *        选摘要必须写 `.line1:not(.item-title)`，否则会把标题一起选中。
 *
 * 坑 3（第 8 节）：父主题 .line1 是 `white-space:nowrap` 的单行截断工具类。
 *        摘要要换行必须 `white-space: normal !important`。
 *        ⚠️ 但标题这里**故意保留** nowrap —— 这个卡型本来就叫「一行」，
 *        标题单行 + ellipsis 正是想要的效果，所以标题不用解除。
 *
 * 坑 4（第 8 节）：父主题 main.css:6364 在移动端把 .item-media 设成 display:none。
 *        ⚠️ 已核对：那条规则只列了 style-sites-big 和 style-sites-max，
 *        **不包含 default**，所以本节不需要写 5 层选择器去压它。
 *
 * 坑 6（本节新发现）：grid 子项会被「块化」(blockification)。
 *        摘要写了 `display:-webkit-box !important`，实测计算值仍是 `flow-root`
 *        —— 因为它是 grid item，浏览器强制块化了。
 *        但 **-webkit-line-clamp 依然生效**：实测同一段 96px 高的文本，
 *        clamp:2 → 元素高 37.2px，clamp:1 → 18.6px，截断和省略号都正常。
 *        所以这里不用改写结构，只是别被 DevTools 里的 flow-root 吓到。
 * ====================================================================== */

/* --- 尺寸变量，要调整整体密度改这里就够 --- */
.io-sub-enhanced .style-sites-default {
  --df-logo: 32px;          /* 圆形 logo 直径 */
  --df-gap-x: 8px;          /* logo 与标题的水平间距 */
  --df-gap-y: 10px;         /* 标题行与简介行的垂直间距 */
  --df-pad: 14px;           /* 卡片内边距 */
  --df-title: 15px;
  --df-desc: 12px;
  --df-desc-lh: 1.6;
  --df-desc-lines: 2;       /* 简介最多几行 */
}

/* --- 卡片外壳 --- */
.io-sub-enhanced .style-sites-default {
  position: relative;
  background: var(--main-bg-color);
  border-radius: var(--theme-border-radius-xl);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.io-sub-enhanced .style-sites-default:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 24px -10px var(--main-shadow);
}

/*
 * --- 主体：两行网格 ---
 *
 * 特异性说明：父主题是
 *   .sites-item .sites-body                   { display:flex; align-items:center }  (0,2,0)
 *   .sites-item.style-sites-default .sites-body { padding:10px }                    (0,3,0)
 * 这里 .io-sub-enhanced .style-sites-default .sites-body 是 (0,3,0) 且后加载，
 * padding 打平手靠顺序赢，display 保险起见加 !important。
 */
.io-sub-enhanced .style-sites-default .sites-body {
  display: grid !important;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "logo title"
    "sum  sum";
  align-items: center;              /* 让 logo 和单行标题上下居中对齐 */
  column-gap: var(--df-gap-x);
  row-gap: var(--df-gap-y);
  width: 100%;
  padding: var(--df-pad);
}

/* 见上方「坑 1」 */
.io-sub-enhanced .style-sites-default .item-body {
  display: contents !important;
}

/*
 * 无图标模式兜底。
 * 后台「主题设置 → 无图标模式」(no_ico) 打开后，io-cards.php:171 那段
 * if ('' === $no_ico || 'big' === $type) 不成立，整个 .item-header 不会输出，
 * 此时 grid 第一列空着，column-gap 会让标题莫名左缩进 8px。
 * 所以这种情况下退回单列。
 */
.io-sub-enhanced .style-sites-default.no_ico .sites-body {
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "title"
    "sum";
}

/* --- 圆形 logo --- */
.io-sub-enhanced .style-sites-default .item-header,
.io-sub-enhanced .posts-item.style-sites-default .item-header {
  grid-area: logo;
  margin-right: 0;                  /* 父主题 .posts-item.sites-item .item-header{margin-right:8px}，间距改由 column-gap 控制 */
  width: var(--df-logo);
  height: var(--df-logo);
}

/*
 * 父主题 .posts-item.sites-item .item-media 是
 *   width:40px; height:0; padding-bottom:100%; border-radius:40px
 * 用 padding-bottom 撑正方形。这里改成显式宽高，padding-bottom 必须清零，
 * 否则卡片会凭空多出 32px 高度。
 */
.io-sub-enhanced .style-sites-default .item-media,
.io-sub-enhanced .posts-item.style-sites-default .item-media {
  width: var(--df-logo);
  height: var(--df-logo);
  min-width: var(--df-logo);
  padding-bottom: 0;
  border-radius: 100%;
}

/*
 * logo 背后那层放大模糊的倒影（hover 时 scale(0)→scale(1)）。
 * 参考站没有这个效果，且它是额外一张背景图。隐藏后 lazy-bg 也不会去加载。
 * 想恢复的话把这条删掉即可。
 */
.io-sub-enhanced .style-sites-default .blur-img-bg {
  display: none;
}

/* --- 标题：单行 + 省略号（见上方「坑 3」，这里刻意保留 nowrap）--- */
.io-sub-enhanced .style-sites-default .item-title,
.io-sub-enhanced .posts-item.style-sites-default .item-title {
  grid-area: title;
  margin: 0;
  min-width: 0;                     /* grid item 默认 min-width:auto，不置 0 的话省略号不生效 */
  font-size: var(--df-title);
  font-weight: 600;
  line-height: 1.4;
  color: var(--main-color);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color 0.2s ease;
}

/* 标题实际文字在 <b> 里，父主题给了 bold，这里统一到 600 */
.io-sub-enhanced .style-sites-default .item-title b {
  font-weight: 600;
}

/* 借鉴参考站：hover 时标题变主题色，给一个明确的「这张卡是可点的」反馈 */
.io-sub-enhanced .style-sites-default:hover .item-title {
  color: var(--theme-color);
}

/*
 * --- 简介：通栏，最多两行 ---
 *
 * 见上方「坑 2」：必须排除 .item-title。
 * min-height 固定住两行高度，这样同一行里简介长短不一的卡片高度仍然一致
 * （实测 12 张卡全部 108.4px）。
 * io-cards.php:186 对 default 类型**总是**输出这个 div（哪怕摘要为空），
 * 所以不用担心某些卡片没有这个元素导致高度错位。
 */
.io-sub-enhanced .style-sites-default .sites-body .line1:not(.item-title) {
  grid-area: sum;
  margin: 0;
  min-width: 0;
  font-size: var(--df-desc);
  line-height: var(--df-desc-lh);
  color: var(--muted-color);
  display: -webkit-box !important;
  -webkit-line-clamp: var(--df-desc-lines);
  -webkit-box-orient: vertical;
  overflow: hidden;
  white-space: normal !important;
  /* 用标准属性 overflow-wrap，不要用废弃别名 word-break:break-word，
   * 后者等价于 overflow-wrap:anywhere，更容易把英文单词从中间劈开 */
  overflow-wrap: break-word;
  min-height: calc(var(--df-desc) * var(--df-desc-lh) * var(--df-desc-lines));
}

/*
 * --- 「直达」箭头 ---
 *
 * 和第 9 节的 max 卡不同，这里**保留**了 togo：
 * 父主题 main.css:6208 已经把它做成「静止 opacity:0，hover 才淡入」的右上角图标，
 * 静止状态完全不影响参考站那种干净的观感，却保住了「不进详情页直接访问」的能力。
 *
 * 唯一要补的是 z-index —— 卡片本体 .sites-body 是个铺满的 <a>，
 * 不抬高层级的话 togo 点不到。实测 elementFromPoint 命中 .icon-gogo，可点。
 *
 * 已知的小瑕疵（父主题原本就有，不是本次改动引入的）：
 * togo 定位在 right:5px/top:5px，标题很长时 hover 出现的箭头会压到标题尾部的省略号。
 * 想彻底避开可以给 .item-title 加 padding-right:18px，代价是标题少显示约一个字。
 */
.io-sub-enhanced .style-sites-default .togo {
  z-index: 2;
}

/* --- 移动端（row-col-2a 两列）---
 *
 * 实测（模拟 414px 视口、两列）：卡片宽 192px，简介栏宽 168px，
 * 两行中文约 24 字，可读性没问题，所以移动端**保留**简介，
 * 不像第 9 节 max 卡那样隐藏（那边是居中窄栏，挤成好几行才不得不藏）。
 *
 * 如果你在真机上还是觉得太密，把下面这段注释解开即可隐藏简介：
 *
 *   .io-sub-enhanced .style-sites-default .sites-body .line1:not(.item-title) {
 *     display: none !important;
 *     min-height: 0;
 *   }
 */
@media (max-width: 767.98px) {
  .io-sub-enhanced .style-sites-default {
    --df-logo: 30px;
    --df-title: 14px;
    --df-pad: 12px;
  }
}


/* =========================================================================
 * 12. 顶部导航右上角图标位：未登录 → 文字「注册/登录」；已登录 → 用户头像
 *
 * 内容本身是 PHP 那边换的（core/io-nav.php，在输出缓冲里把
 * <i class="iconfont icon-user icon-lg"> 换掉），这里只负责样式：
 *   未登录 —— 让按钮从「38×38 的方形图标位」变成能放下文字的胶囊
 *   已登录 —— 把头像收到 30px 并加一圈描边
 *
 * ── 为什么不用纯 CSS 的 ::after content 来塞文字 ──────────────
 *
 * 用 content 也能显示出字，但那是生成内容：
 *   · 选不中、复制不出来
 *   · 主题自带的多语言切换（io_translate_render_switcher）翻译不到
 *   · 搜索引擎读不到
 * 所以文案走 PHP 生成真实文本节点，CSS 只管样式。
 *
 * ── 为什么胶囊那几条要 :not(.logged-in) ──────────────────────
 *
 * 胶囊是给文字用的（width:auto 撑到 84.9px）。已登录时那里放的是 30px 头像，
 * 不加这个限定的话，登录后头像会被塞进一个莫名其妙的宽胶囊里。
 * 头像那几条则不需要限定 —— .io-sub-nav-avatar 这个类只有已登录时才会出现。
 *
 * `logged-in` 是 WordPress 核心 body_class() 在登录时加的类
 * （子主题 header.php:38 有 body_class(io_body_class())），
 * 跟 PHP 侧的 is_user_logged_in() 判断天然一致，不会出现两边打架。
 *
 * ── 特异性 ───────────────────────────────────────────────────
 *
 * 父主题 main.css:1288 `.header-icon-btn > a` 把宽高写死成 38×38：
 *   .header-icon-btn > a { display:flex; font-size:17px; margin:2px;
 *                          width:38px; height:38px }
 * 那是 (0,1,1)；这里 `.io-sub-enhanced:not(.logged-in) .header-icon-btn.nav-login > a`
 * 是 (0,4,1)，压得住，不需要 !important。
 *
 * ── 移动端 ───────────────────────────────────────────────────
 *
 * 这个 <li> 父主题带了 `d-none d-md-block`，768px 以下本来就不显示，
 * 移动端的登录入口在底部 tabbar，本节不影响移动端。
 *
 * ── 实测（未登录，视口 1400）─────────────────────────────────
 *
 *   按钮 <a> ....... 84.9 × 38（原来 38 × 38）
 *   <li> ........... 88.9 × 42
 *   .header-tools .. 84 → 130.9px，右侧搜索图标位置不变，
 *                    整体仍在 1372px 的导航宽度内，没有挤动主菜单
 * ====================================================================== */

.io-sub-enhanced:not(.logged-in) .header-icon-btn.nav-login > a {
  width: auto;                      /* 解除父主题写死的 38px */
  height: 38px;
  padding: 0 12px;
  border-radius: 999px;
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  color: var(--main-color);
  white-space: nowrap;              /* 「注册/登录」不允许在斜杠处断行 */
  transition: color 0.2s ease, background-color 0.2s ease;
}

.io-sub-enhanced:not(.logged-in) .header-icon-btn.nav-login > a:hover {
  color: var(--theme-color);
  background: var(--muted-bg-a-color);
}

/*
 * ── 已登录：人形图标 → 用户头像 ──────────────────────────────
 *
 * PHP 输出的是 <span class="io-sub-nav-avatar avatar-img"><img class="avatar …"></span>，
 * 顺着父主题自己的头像容器约定写的（main.css:1642）：
 *   .avatar-img { --this-size:38px; width:var(--this-size); height:var(--this-size) }
 *   .avatar     { width:100%; height:100%; object-fit:cover; border-radius:100px }
 * 所以尺寸只要覆盖 --this-size 就够了，不用去动里面的 img。
 *
 * 特异性：`.io-sub-enhanced .nav-login .io-sub-nav-avatar` 是 3 个类，
 * 压得住父主题 1 个类的 `.avatar-img`。
 *
 * 这几条不需要 :not(.logged-in) —— .io-sub-nav-avatar 只有已登录时才存在。
 *
 * 30px 装在父主题原本 38×38 的按钮里，四周留 4px，不改变导航高度和其他图标位置。
 */
.io-sub-enhanced .nav-login .io-sub-nav-avatar {
  --this-size: 30px;
  border-radius: 100px;
  box-shadow: 0 0 0 2px var(--muted-bg-a-color);
  transition: box-shadow 0.2s ease;
}

/* 悬停时描边变主题色，作为「这里可以点开」的反馈 */
.io-sub-enhanced .nav-login > a:hover .io-sub-nav-avatar {
  box-shadow: 0 0 0 2px var(--theme-color);
}

/*
 * ── 想要更强的引导（实心主题色按钮）就用下面这段 ──────────────
 *
 * 把上面两条规则里的 color / background 换掉即可，
 * 或者直接把这段注释解开（它在后面，会覆盖上面）：
 *
 * .io-sub-enhanced:not(.logged-in) .header-icon-btn.nav-login > a {
 *   color: #fff;
 *   background: var(--theme-color);
 * }
 * .io-sub-enhanced:not(.logged-in) .header-icon-btn.nav-login > a:hover {
 *   color: #fff;
 *   background: var(--theme-color);
 *   filter: brightness(1.08);
 * }
 *
 * ── 想换文案 ─────────────────────────────────────────────────
 *
 * 不要改 CSS，改 PHP 那边的 filter（改完文案宽度会自适应）：
 *
 *   add_filter( 'io_sub_nav_login_label', function() { return '登录 / 注册'; } );
 *
 * ── 想换头像大小 ─────────────────────────────────────────────
 *
 * 改上面 .io-sub-nav-avatar 的 --this-size 即可（这是显示尺寸）。
 * 取图尺寸固定 96，别去动 —— 那是为了和下拉面板里的头像共用同一次请求，
 * 详见 core/io-nav.php 的说明。
 */
