/* home-directory.css — Love8.me 首页目录模板的共享样式表。
   全部 11 个正式语言导航首页共用这一张，视觉与交互一致。

   原本是 home-variants/zh-hans/index.html 里的内联 <style>（1685 行）。外置的原因是
   en 变体要复用同一套设计 —— 两个页面各存一份会立刻分叉，这正是被删掉的
   assets/css/en/directory-home.css 的由来：它是这段样式的一个分叉，大量规则逐字节相同，
   只是砍掉了侧边栏、返回顶部和富 tooltip。

   两条不能破坏的约束：
   1. <link> 必须排在 language-switcher.css 之后 —— 原内联块就在它们
      后面，同特异性时靠源顺序取胜。挪到前面会静默翻转一批平局。
   2. 不得出现 @import。 */

/* Guides belong to the existing full directory, as a text index. */
.guide-index { margin: 28px 0; padding: 20px; border: 1px solid #f2dbe3; border-radius: 10px; background: #fff; }
.guide-index h2 { margin: 0 0 12px; font-size: 18px; }
.guide-index ul { margin: 0; padding-inline-start: 22px; columns: 2 260px; column-gap: 32px; }
.guide-index li { break-inside: avoid; margin-bottom: 8px; }
.guide-index a { text-decoration: underline; text-underline-offset: 3px; overflow-wrap: anywhere; }

:root {
  --page: #f6f7fb;
  --surface: #ffffff;
  --surface-muted: #fff4f8;
  --ink: #17212b;
  --muted: #5b6876;
  --line: #DDD;
  --accent: #d6336c;
  --accent-dark: #a61e4d;
  --hot: #ff1744;
  --soft-hot: #fff1f6;
  --shadow: 0 10px 24px rgba(214, 51, 108, 0.12);
  --max: 1160px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  min-width: 320px;
  margin: 0;
  color: var(--ink);
  background: var(--page);
  /* background-color:#999; */
  font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, "Microsoft YaHei", sans-serif;
  line-height: 1.55;
  /* 给左右下角两颗悬浮按钮（.desc-toggle / .back-to-top）让位：滚到底时，页脚最后一行
     （版权行）必须完整落在按钮上方。原先只有 20px，版权行正好压在两颗按钮那一条上
     （2026-10-17 站主反馈）。
     取值 = 按钮 bottom 20px + 按钮高 26.4px + 约 10px 间隙；窄屏那档在 640 块里。
     改按钮的 bottom 或尺寸时要一起改这里。≥1500px 时按钮挪进装订线、不再压内容，
     这里不另降回去 —— 多出的留白无害，省一条断点规则。 */
  padding-bottom: 56px;
}

/* 俄语首页的字体栈（2026-09-30）—— 本表原本零 locale 规则，这是第一条。
 *
 * 为什么需要它：上面那条栈的第一项是 system-ui，而 system-ui 解析成什么取决于
 * **访客的系统语言**，不是页面语言。CDP 的 CSS.getPlatformFontsForNode 在中文
 * Windows 上实测，/home-variants/ru/ 的正文 57 个字符全部由 "Microsoft YaHei UI"
 * 渲染 —— 用一个中文字体画西里尔。YaHei 确实带西里尔字形，但那是为了和汉字并排
 * 而设计的，字重与字形都偏离俄语读者的预期。
 *
 * 修法是把 system-ui 拿掉，改为逐平台点名：Apple 用 SF Pro、Windows 用 Segoe UI、
 * Android 用 Roboto、其余用 Noto Sans。这四个都是完整覆盖西里尔的界面字体，
 * 而且都不含 CJK，所以不会再被系统语言牵着走。俄语页不含 CJK 文字，无需 CJK 兜底。
 *
 * 作用域到 html[lang="ru"]，其余变体不受影响（下面那条 ja 规则是另一件事，各管各的）。
 * 注意：仓库里的层叠求解器不判断属性**值**，会把这两条规则都当成命中所有页面 ——
 * 它们只声明 font-family，与任何生成类都不冲突，但今后往这里加别的属性要留意。
 */
html[lang="ru"] body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Noto Sans", Arial, sans-serif;
}

/* 日语首页的字体栈（2026-09-30）—— 与上面那条同一个根因，但后果更重。
 *
 * CDP 实测（中文 Windows）：/home-variants/ja/ 的正文 41 个字符全部由 "Microsoft YaHei UI"
 * 渲染。这不只是「换了个字体」—— 中日共享的汉字在两地有不同的标准字形，
 * 直 / 骨 / 収 / 対 / 音 / 今 这些字用中文字体画出来，日语读者一眼就能看出不对。
 *
 * 排序是「拉丁在前、日文在后」的常规做法：前五个都**不含 CJK**，
 * 所以它们只接走拉丁字母与数字（品牌名 FANZA / MissAV 之类），
 * 汉字与假名逐字回退到后面的日文字体。system-ui 同样要拿掉 —— 它就是把
 * 两类文字一起吞掉的那一项。
 *
 * 日文字体按平台点名：Hiragino 系是 macOS / iOS，Yu Gothic UI 是 Windows 8.1+ 的
 * 界面变体（比 Yu Gothic 行距更紧，更适合 UI），Meiryo 兜住更旧的 Windows，
 * Noto Sans JP 兜住 Android / Linux。
 */
html[lang="ja"] body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial,
    "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic UI", "Yu Gothic", Meiryo,
    "Noto Sans JP", sans-serif;
}

/* 韩语首页的字体栈（2026-09-30）—— 同一个根因，但只坏了一半。
 *
 * CDP 实测（中文 Windows）：/home-variants/ko/ 的正文里谚文 30 个字符已经由
 * "Malgun Gothic" 正确渲染 —— 因为 Microsoft YaHei 不含谚文，system-ui 抓不走它，
 * 逐字回退到了 sans-serif 背后的系统韩文字体。剩下的 11 个字符（拉丁品牌名、
 * 空格与标点）仍落在 "Microsoft YaHei UI" 上，所以是中文字体画拉丁字形、
 * 中文宽度的标点。比 ja 那个「汉字字形错」轻，但同样没道理。
 *
 * 排序与 ja 同理：前五个不含 CJK / 谚文，只接走拉丁；谚文逐字回退到后面三个。
 * Apple SD Gothic Neo 是 macOS / iOS，Malgun Gothic 是 Windows Vista+，
 * Noto Sans KR 兜住 Android / Linux。
 */
html[lang="ko"] body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial,
    "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", sans-serif;
}

/* 繁体中文首页的字体栈（2026-09-30）—— 与 ja 同型，而且更隐蔽。
 *
 * 基础栈里唯一的 CJK 字体是 "Microsoft YaHei"，它是**简体中文**字体。
 * 它确实收录繁体字，但字形按大陆规范画：同一个码位的 骨 / 直 / 青 / 說 / 過 / 述
 * 在大陆与台湾标准里写法不同，用 YaHei 渲染繁体页，台港读者看到的是「大陆写法的繁体字」。
 * 残留简体字校验器也抓不到这件事 —— 码位本身完全正确，错的是字形。
 *
 * 排序同 ja / ko：前五个不含 CJK，只接走拉丁；汉字逐字回退到繁体字体。
 * PingFang TC 是 macOS / iOS，Microsoft JhengHei（微軟正黑體）是 Windows，
 * Noto Sans TC 兜住 Android / Linux。三者都按台湾标准字形 —— 与本页的台湾用词一致；
 * 香港读者在 Windows 上默认也是正黑体，所以不另列 PingFang HK。
 */
html[lang="zh-Hant"] body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial,
    "PingFang TC", "Microsoft JhengHei UI", "Microsoft JhengHei", "Noto Sans TC", sans-serif;
}

a {
  color: inherit;
  text-decoration: none;
}

button,
input {
  font: inherit;
}

button {
  cursor: pointer;
}

button:focus-visible,
a:focus-visible,
input:focus-visible {
  outline: 3px solid rgba(214, 51, 108, .28);
  outline-offset: 3px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.topbar {
  background: var(--page);
}

.topbar-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 18px;
  width: min(var(--max), calc(100% - 40px));
  min-height: 64px;
  margin: 0 auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: max-content;
  color: #3a2f2a;
}

.brand-mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  color: transparent;
  font-size: 0;
  font-weight: 800;
  border-radius: 10px;
  background: url("/assets/images/logo.png") center / contain no-repeat;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
}

.brand-text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.brand-name {
  font-size: 18px;
  font-weight: 545;
}

.brand-tagline {
  font-size: 12px;
  font-weight: 545;
}

.top-links {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--muted);
  font-size: 14px;
}

.bookmark-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-height: 34px;
  padding: 5px 9px;
  color: var(--accent-dark);
  font-size: 13px;
  line-height: 1.2;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff4f8;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .bookmark-button:hover {
    color: var(--hot);
    border-color: #e7a8bd;
    background: var(--soft-hot);
  }
}

.bookmark-icon {
  font-size: 17px;
  line-height: 1;
}

.bookmark-toast {
  position: absolute;
  z-index: 35;
  top: calc(100% + 8px);
  right: 0;
  width: max-content;
  max-width: min(290px, calc(100vw - 28px));
  margin: 0;
  padding: 8px 10px;
  color: #34414d;
  font-size: 12px;
  line-height: 1.45;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #fff;
  box-shadow: 0 6px 16px rgba(23, 33, 43, .14);
  transform: translateY(-4px);
  transition: opacity .16s ease, transform .16s ease, visibility .16s ease;
}

.bookmark-toast.is-visible {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}

.site-tooltip {
  position: fixed;
  z-index: 60;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  width: min(300px, calc(100vw - 24px));
  padding: 14px 16px;
  color: #34414d;
  font-size: 13px;
  line-height: 1.6;
  text-align: center;
  pointer-events: none;
  visibility: hidden;
  opacity: 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 16px 36px rgba(23, 33, 43, .2);
  transition: opacity .16s ease, visibility .16s ease, transform .16s ease;
}

.site-tooltip--above {
  transform: translateY(4px);
}

.site-tooltip--below {
  transform: translateY(-4px);
}

.site-tooltip::after {
  position: absolute;
  left: var(--arrow-left, 50%);
  width: 14px;
  height: 14px;
  content: "";
  background: #fff;
  transform: translateX(-50%) rotate(45deg);
}

.site-tooltip--above::after {
  bottom: -8px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  border-radius: 0 0 3px;
}

.site-tooltip--below::after {
  top: -8px;
  border-top: 1px solid var(--line);
  border-left: 1px solid var(--line);
  border-radius: 3px 0 0;
}

.site-tooltip.is-visible {
  visibility: visible;
  opacity: 1;
  transform: translateY(0);
}

.site-tooltip-name {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--accent-dark);
  font-size: 14px;
  font-weight: 700;
}

.site-tooltip-icon {
  width: 20px;
  height: 20px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: #fff;
}

.site-tooltip-desc {
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.6;
}

/* 「返回顶部 / 跳到底部」按钮样式在 nav-floating-tools.css。首页与扩展目录共用，不要在这里再写一套。 */

/* 「显示描述 / 关闭描述」开关。**两端都显示**（2026-09-18 起）。

   两个断点的默认态是相反的，这是这颗按钮最容易搞错的地方：
     窄屏 ≤640px  描述默认**隐藏**（省纵向空间），按钮用来调出来；
                  浮层只绑 hover/focus，触屏够不着，所以这是手机用户看到描述的唯一入口。
     桌面 ≥641px  描述默认**显示**，按钮用来关掉（嫌卡片太高时）。

   所以「可见」这件事在 CSS 里需要两条方向相反的规则：
     body.show-card-desc .site-card-desc   在 640px 块里，把窄屏的默认隐藏顶回去；
     body.hide-card-desc .site-card-desc   在基础层，把桌面的默认显示压下去。
   两个类互斥，由脚本保证同一时刻只挂一个 —— 两条都是 (0,2,0)，同时存在就只看源顺序了。

   位置：跟 back-to-top 左右对称（左下角，两者 bottom 相同）。 */

/* 桌面端关掉描述用的那条。
   **刻意不声明 `display`** —— 这是窄屏行为不受影响的全部机制：本条是 (0,2,0)，
   若它写了 display，就会压过 640px 块里那条 (0,1,0) 的 `display: none`，
   窄屏的描述会变成「参与 row 弹性布局的零高元素」，把带 ellipsis 的站名挤没
   （正是 :2144 注释记过的那个故障）。不写 display，窄屏那条靠源顺序照常生效。

   三条取值各有非有不可的理由：
   · max-height: 0  —— display 不可动画，塌陷只能走 max-height（基础层已给紧界 56px）。
   · margin-top: -4px —— .site-card 是 column + gap: 4px。`display:none` 的元素不参与
     flex 布局、不占 gap，而 max-height:0 的元素**仍然参与**，不补偿的话关闭态每张卡
     凭空高 4px，174 张累加起来肉眼可见。
   · visibility: hidden —— 没有 display:none 了，塌陷后的描述仍在无障碍树里，
     读屏会念出 174 段看不见的文字。visibility 放进 transition 列表后是「转向 hidden
     在动画末尾才翻、转向 visible 立刻翻」，正好是要的时序。

   注意：JS 侧的浮层判定必须同步改成读 offsetHeight —— 它原本读 computed display，
   改完之后恒为 -webkit-box，会让「关掉描述后靠悬停浮层看」这条设计静默失效。 */
body.hide-card-desc .site-card-desc {
  max-height: 0;
  margin-top: -4px;
  opacity: 0;
  visibility: hidden;
}

/* 「显示描述 / 关闭描述」按钮样式在 nav-floating-tools.css。 */

.page {
  width: min(var(--max), calc(100% - 40px));
  margin: 0 auto;
}

.search-area {
  padding: 4px 0px 10px 0px;
}

.search-form {
  --search-button-width: 86px;
  position: relative;
  display: flex;
  align-items: center;
  max-width: 760px;
  margin: 0 auto;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: #fff;
  box-shadow: 0 3px 10px rgba(23, 33, 43, .05);
}

.search-input {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  height: 48px;
  padding: 0 46px 0 14px;
  color: var(--ink);
  font-size: 16px;
  border: 0;
  outline: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
}

.search-input::placeholder {
  color: #89949f;
}

/* ── 焦点态：必须写在这里，否则会渲染成一条诡异的淡红色竖线 ──────────────
   站主 2026-09-22 报「搜索前面多了一条淡红色竖线，鼠标光标在搜索框里才出现」。
   成因是三条规则叠在一起，每一条单看都没问题：

     1. 全局 `input:focus-visible { outline: 3px solid rgba(214,51,108,.28);
        outline-offset: 3px }`（:64）。注意 `.search-input` 自己那条 `outline: 0`
        （:543）**压不住它** —— (0,1,0) 输给 (0,1,1)。
     2. 文本输入框在**任何**方式获得焦点时都匹配 `:focus-visible`（规范如此，
        不像按钮只在键盘操作时匹配），所以鼠标点一下就会亮。
     3. `.search-form` 是 `overflow: hidden`（:527）。

   于是那圈描边的上/下/左三边都落在表单内容盒之外、被裁掉，而**右边**那一段不同：
   `.search-input` 是 `flex: 1 1 auto`，它的右缘落在表单**中间**（右侧 86px 归按钮），
   描边右移 3px 后仍在表单内部，逃过裁剪 —— 四条边只活下来一条，就成了那条竖线。
   颜色 rgba(214,51,108,.28) 压白合成为 #F4C6D6，正是「淡红色」。

   **这个缺陷在改动之前就存在**，只是当时按钮是实心 #d6336c 粉底，一条浅粉线贴在
   粉底上看不出来；按钮改成透明底之后它才显形。

   修法：关掉那圈注定被裁的描边，把焦点指示移到**整个字段的外框**上 ——
   字段才是视觉单元，而且外框不受 overflow 裁剪。
   #DDD -> var(--accent) 状态间对比 3.40:1，过 WCAG 2.4.11 的 3:1。 */
.search-input:focus-visible {
  outline: 0;
}

.search-form:focus-within {
  /* border-color:var(--accent-dark); */
  border-color:#BBB;
}

.search-clear {
  display: none;
  position: absolute;
  z-index: 1;
  top: 50%;
  right: calc(var(--search-button-width) + 5px);
  width: 36px;
  height: 36px;
  margin: 0;
  color: #788490;
  font-size: 26px;
  font-weight: 300;
  line-height: .9;
  border: 0;
  border-radius: 50%;
  background: transparent;
  transform: translateY(-50%);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .search-clear:hover {
    color: var(--ink);
    background: #eef2f4;
  }
}

.search-clear.is-visible {
  display: block;
}

.search-button {
  flex: 0 0 auto;
  align-self: stretch;
  min-width: var(--search-button-width);
  color: var(--accent);
  font-weight: 600;
  border: 0;
  border-left: 1px solid #DDDDDD;
  color: var(--accent-dark);
  /* **本按钮刻意没有任何边界，这是站主 2026-09-22 看过实物后定的。**
     2026-09-22 之前把输入区和按钮分开的只有那块粉底本身（底色对比 4.62:1）；
     反色之后曾加过一条 `border-left: 1px solid var(--line)`（与 .category-more-link 同型），
     站主看了真实渲染后要求去掉 —— 他两次把那条 1px 灰线描述成「淡红色」，
     大概率是 Windows 缩放下竖线吃到子像素色边。
     所以现在 .search-form(:530 #fff) / .search-input(:546 transparent) /
     .search-clear(:568 transparent) 与本按钮是一整片不间断的白，分界对比 1.00:1。
     这是**有意的**：不要再「顺手」把线加回来。副作用是清空「×」与按钮文字相距仅
     13px（≤640px 10px）且中间空无一物，两个点击区的边界只能靠文字本身区分。 */
  /* 写 transparent 而不是写死 #fff：白色只由 .search-form(:530) 一处提供，
     两个兄弟节点（.search-input :546 / .search-clear :568）也都是 transparent，
     今天的渲染结果与 #fff 逐像素相同，但表单底色将来若变，按钮会跟着走。 */
  background: transparent;
  font-size: 16px;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。
   原来是 background: var(--accent-dark)，白底之后照旧会在悬停时闪回整块深粉，
   正好与「不要太显眼」相反。改成文字加深 + 极浅粉底，两个取值都是表里已有的令牌。 */
@media (hover: hover) {
  .search-button:hover {
    
     color: var(--accent);
    /* background: var(--soft-hot); */
  }
}

/* 触屏的高亮靠 `:focus`，不是 `:hover` 也不是 `:focus-visible` —— 口径与理由见 :354 那段
   （站主 2026-09-18 定的）。这颗按钮原本靠粉色填充提示自己在哪，底色一变透明，
   触屏点按就完全没有反馈了，所以这条是本次改动的必需项而不是顺手加的。
   取值与 hover 同一对（--accent -> --accent-dark），保持「点了变深、焦点离开恢复」。 */
.search-button:focus,
.search-button:active {
  color: var(--accent-dark);
}

/* 但只靠变色不够：#d6336c -> #a61e4d 的状态间对比只有 1.56:1，低于 WCAG 2.4.11 对焦点
   指示器的 3:1。键盘用户本该由全局 button:focus-visible(:62) 那条描边兜底，而
   .search-form 是 overflow: hidden，outline-offset: 3px 把描边推到按钮盒外，
   上/右/下三边全被裁掉 —— 这个缺陷今天就存在，只是粉底还在，至少看得见按钮在哪。
   负 offset 把同一条描边改画进按钮内部，不被裁。全局那条规则本身不动。 */
.search-button:focus-visible {
  outline-offset: -3px;
}

.search-feedback {
  display: none;
  max-width: 760px;
  min-height: 20px;
  margin: 9px auto 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.45;
  text-align: center;
}

.search-feedback.is-visible {
  display: block;
}

/* 有匹配结果时的那条统计（「找到 123 个匹配入口（常用入口 2 个，分类目录 121 个）。」）
   站主 2026-09-22 判定为多余 —— 结果本身就排在它正下方，再报一遍数字是噪音。

   但**不能直接清空 textContent**：#search-feedback 是 role="status" aria-live="polite"，
   是读屏用户唯一能知道「边打字边筛选确实生效了」的渠道（搜索不跳转、不发请求，
   页面上没有任何别的信号）。所以文字保留在 live region 里继续播报，只是不再视觉呈现。

   为什么不复用 .sr-only(:69)：那条没有 display，压不住本元素 display: none；
   而且 .search-feedback 的 min-height: 20px 会盖过 .sr-only 的 height: 1px
   （min-height 永远赢 height），元素照样占 20px 高，行还是会撑开。
   所以这里自带 min-height: 0 与 margin: 0，(0,2,0) 稳压 (0,1,0)。

   无结果提示（.is-empty）与空词提示（.is-hint）**不受影响，仍然可见** ——
   那两种情况下页面上没有结果可看，文字是唯一的解释。 */
.search-feedback.is-count-only {
  position: absolute;
  width: 1px;
  height: 1px;
  min-height: 0;
  padding: 0;
  margin: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

/* 「未找到与"xxx"相关的站点或分类。」
   原来是 var(--hot) #ff1744：13px 正文（:675 的 font-size）压在页面底 --page #f6f7fb 上
   只有 **3.59:1**，低于正文 AA 的 4.5:1。而它偏偏是「结果全没了」时屏幕上唯一还剩的文字。
   换 --accent-dark 是 6.73:1，达标；--accent 只有 4.31:1，仍然不够，不要选它。
   语气上也更合适：用户没做错任何事，不该用全站最烫的颜色标他。--hot 在这张表里的其余
   用法都是「当前项 / 正在交互」，让它保持那个含义。
   要保留比 .is-hint 重一点的层次就靠字重，不要靠色相。 */
.search-feedback.is-empty {
  color: var(--accent-dark);
  font-weight: 600;
}

.search-feedback.is-hint {
  color: var(--accent-dark);
}

.category-navigator {
  grid-area: sidebar;
  display: flex;
  flex-direction: column;
  margin: 0;
  overflow: hidden;
  border: 1px solid var(--line);
  /* 必须与 .directory-panel 的圆角同值 —— 两者在 .category-shell 里左右并排、顶边对齐，
     取值不同时两个顶角的弧度差直接可见。改一个就要改另一个。
     头部那层方角渐变靠本容器的 overflow: hidden 裁圆，所以
     .category-navigator-header 在桌面端不需要自己的 border-radius（窄屏需要，见 640px 块）。 */
  border-radius: 8px;
  background: var(--surface);
  box-shadow: 0 6px 18px rgba(214, 51, 108, .07);
  position: sticky;
  top: 16px;
  align-self: start;
  max-height: calc(100vh - 32px);
}

.category-navigator-header {
  position: relative;
  flex: 0 0 auto;
  padding: 10px 14px 10px 18px;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--soft-hot), var(--surface));
}

/* 标题左侧的粉色竖条，替代过去仅靠字重区分层级的做法。 */
.category-navigator-header::before {
  content: "";
  position: absolute;
  top: 13px;
  left: 8px;
  width: 3px;
  height: 16px;
  border-radius: 3px;
  background: linear-gradient(180deg, var(--accent), var(--hot));
}

/* 折叠开关。桌面端它必须**看不出来是个按钮** —— 那里面板不折叠（sticky 侧栏本来就在视口内），
   这层重置让标题栏的渲染与它还是一个裸 <strong> 时一致：无边框、无内距、无按钮字体。
   「点击收起 / 点击展开」与 caret 同样只在窄屏出现。 */
.category-navigator-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin: 0;
  padding: 0;
  color: inherit;
  font: inherit;
  text-align: left;
  border: 0;
  border-radius: 0;
  background: none;
  cursor: default;
}

.category-navigator-hint,
.category-navigator-caret {
  display: none;
}

.category-navigator-title {
  color: var(--accent-dark);
  font-size: 14px;
  font-weight: 750;
  letter-spacing: .02em;
  white-space: nowrap;
}

/* 折叠动画用的裁剪层（标记里包在 .category-groups 外面）。
   桌面端让它**完全不参与布局** —— `display: contents` 之后 .category-groups 仍然是
   .category-navigator 的直接 flex 子项，侧栏的 `overflow-y: auto` 滚动与高度分配
   与加这层之前逐字节一致。它只在 640px 块里恢复成普通块，去承担高度过渡。 */
.category-groups-clip {
  display: contents;
}

.category-groups {
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 8px;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: #efc9d7 transparent;
}

.category-groups::-webkit-scrollbar {
  width: 6px;
}

.category-groups::-webkit-scrollbar-thumb {
  border-radius: 6px;
  background: #efc9d7;
}

.category-group-button {
  position: relative;
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 38px;
  padding: 7px 10px 7px 11px;
  color: var(--ink);
  font-size: 14px;
  font-weight: 550;
  line-height: 1.3;
  border-radius: 9px;
  background: transparent;
  transition: background-color .18s ease, color .18s ease, box-shadow .18s ease, border-color .18s ease;
}

/* 逐条分隔线。用伪元素而非 border-bottom，好让它在 hover 时单独淡出，
   不跟圆角高亮底色的下缘打架。 */
.category-group-button::after {
  content: "";
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: var(--line);
  transition: opacity .18s ease;
}

.category-group-button:last-child::after {
  opacity: 0;
}

/* 高亮行自己的分隔线、以及它上方那条，一起让位给圆角底色。 */
.category-group-button.is-active::after,
.category-group-button[aria-current="location"]::after,
.category-group-button:has(+ .category-group-button.is-active)::after,
.category-group-button:has(+ .category-group-button[aria-current="location"])::after {
  opacity: 0;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-group-button:hover::after,
  .category-group-button:has(+ .category-group-button:hover)::after {
    opacity: 0;
  }
}

/* 当前项指示条：用伪元素而非 border-left，避免占位导致文字左右跳动。 */
.category-group-button::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 3px;
  width: 3px;
  height: 0;
  border-radius: 3px;
  background: var(--hot);
  transform: translateY(-50%);
  transition: height .18s ease;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-group-button:hover {
    color: var(--hot);
    background: var(--soft-hot);
  }
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-group-button:hover::before {
    height: 12px;
  }
}

.category-group-button.is-active,
.category-group-button[aria-current="location"] {
  color: var(--hot);
  font-weight: 700;
  background: var(--soft-hot);
}

.category-group-button.is-active::before,
.category-group-button[aria-current="location"]::before {
  height: 18px;
}

/* emoji 字形宽高不一，统一装进固定尺寸的圆角底板里对齐。 */
.category-group-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  overflow: hidden;
  border-radius: 8px;
  background: var(--surface-muted);
  font-size: 13px;
  line-height: 1;
  text-align: center;
  transition: background-color .18s ease, transform .18s ease;
}

.category-group-button.is-active .category-group-icon,
.category-group-button[aria-current="location"] .category-group-icon {
  background: #ffe0ea;
  transform: scale(1.06);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-group-button:hover .category-group-icon {
    background: #ffe0ea;
    transform: scale(1.06);
  }
}

.category-group-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.category-group-chevron {
  flex: 0 0 auto;
  color: #d8b9c4;
  opacity: .7;
  transition: transform .18s ease, color .18s ease, opacity .18s ease;
}

.category-group-button.is-active .category-group-chevron,
.category-group-button[aria-current="location"] .category-group-chevron {
  color: var(--hot);
  opacity: 1;
  transform: translateX(2px);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-group-button:hover .category-group-chevron {
    color: var(--hot);
    opacity: 1;
    transform: translateX(2px);
  }
}

.category-groups a[hidden] {
  display: none !important;
}

.direct-grid {
  display: grid;
  /* 按实际入口数排两行：10 个用五列，6 个用三列；不补空白占位。 */
  grid-template-columns: repeat(var(--shortcut-columns, 5), minmax(0, 1fr));
  margin: 0 auto;
  padding: 14px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #fff;
  box-shadow: 0 3px 12px rgba(23, 33, 43, .035);
}

.direct-site {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  min-width: 0;
  min-height: 86px;
  padding: 8px 5px;
  color: #26333d;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid transparent;
  border-radius: 8px;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, background-color .15s ease, color .15s ease;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .direct-site:hover {
    color: var(--hot);
    border-color: #f0c6d5;
    background: var(--soft-hot);
    box-shadow: 0 4px 12px rgba(214, 51, 108, .1);
    transform: translateY(-1px);
  }
}

/* 搜索筛选依赖 hidden 属性；显式提高优先级，防止下面的 display:flex 覆盖浏览器默认隐藏规则。
   这张清单必须**逐条枚举**每一种会被 refresh() 打上 hidden 的元素 —— 漏掉哪个，
   哪个就永远不会消失。`.site-card` 就漏过：它自己的 `display: flex` 是作者层规则，
   压得过 UA 样式表的 `[hidden] { display: none }`，于是 zh-hans 首页搜索时
   不匹配的卡片**原地不动**，只有整行会消失；而 en 用的 `.site-link` 在清单里，
   同样的搜索在英文首页表现正常。两个首页的搜索体验因此差了一截。

   2026-09-22 起 refresh() 还会给 `.category-group-button`（侧栏大类按钮）打 hidden。
   它同样带作者层 `display: flex`，同样压得过 UA 规则 —— 今天不出事**只是因为**另有一条
   独立的 `.category-groups a[hidden] { display: none !important }` 恰好盖住了它。
   那条规则一旦被当成遗留清掉、或按钮被挪出 `.category-groups`，`.site-card` 那次事故
   会原样重演，而且没有任何校验器会红。所以在这里也列一条，两处互相可见。 */
.direct-grid[hidden],
.direct-site[hidden],
.site-link[hidden],
.site-card[hidden],
.category-group-button[hidden],
.category-row[hidden] {
  display: none !important;
}

.direct-favicon {
  display: block;
  width: 40px;
  height: 40px;
  box-sizing: border-box;
  padding: 3px;
  object-fit: contain;
  border-radius: 9px;
  background: #fff;
  border: 1px solid var(--line);
  box-shadow: 0 3px 7px rgba(23, 33, 43, .12);
}

.direct-site span:last-child {
  overflow: visible;
  max-width: 100%;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

.directory {
  padding: 0px 0 0px;
  margin-top: 10px;
}

.other-directory {
  padding: 0px 0 0px;
  margin-top: 10px;
}

.other-directory h2 {
  font-size: 18px;
  margin: 0 0 5px 4px;
  color: var(--accent-dark);
}

.category-shell {
  display: grid;
  grid-template-columns: 240px minmax(0, 1fr);
  grid-template-areas:
    "sidebar top"
    "sidebar bottom";
  align-items: start;
  gap: 16px;
}

.category-main-top {
  grid-area: top;
}

.category-main-bottom {
  grid-area: bottom;
}

.directory-panel {
  overflow: visible;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  box-shadow: 0 3px 12px rgba(23, 33, 43, .035);
}

.category-row {
  display: block;
  scroll-margin-top: 18px;
  border-bottom: 1px solid var(--line);
}

.category-row:last-child {
  border-bottom: 0;
}

.category-heading {
  margin: 0;
}

.category-row:first-child .category-heading {
  border-radius: 7px 7px 0 0;
}

.category-row:first-child .category-name {
  border-top-left-radius: 7px;
}

.category-row:first-child .category-more-link:last-child,
.category-row:first-child .category-name:last-child {
  border-top-right-radius: 7px;
}

/* 标题行上淡粉底，把它与下面白底的链接区分开。原先一个分类行里叠了四层白
   （.directory-panel / 这里 / .category-links / .site-link），中间只有一条 1px 发线，
   而那条线与行间分隔线同色同粗，所以读不出「标题」和「内容」是两个区域。

   2026-09-21 站主要求：改成与左侧「成人内容分类」标题栏**同一个**渐变，
   逐字节抄 .category-navigator-header 的取值（:650）—— 两条标题栏在同一屏里左右并排，
   一个纯色一个渐变会读成「两种层级」，而它们其实是同一层级的两个入口。
   同样不新增颜色：--soft-hot 与 --surface 都是表里已有的变量。
   渐变收在 --surface（白）上，与下面 .category-links 的白底同色，所以
   下边框那条 var(--line) 发线从「色块边界」升级成唯一的分隔依据 —— 它必须留着。
   两条标题栏高度相近（这里 min-height 48px，侧栏那条约 40px），所以同一条
   180deg 渐变在两处的观感一致，不需要为高度差改角度或色标。 */
.category-row--enhanced .category-heading {
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, var(--soft-hot), var(--surface));
}

/* 按钮必须透明。它是 flex: 1 1 auto，占满整条标题行，自带的 background: #fff（:832）
   会把上面那层粉底整个盖住 —— 只改 .category-heading 是看不出任何变化的。 */
.category-row--enhanced .category-name {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  border-bottom: 0;
  color: #282128;
  background: transparent;
}

/* 悬停时**不动背景**：文字已经从 #282128 变成 var(--hot)，反馈足够，再加深底色是多余的。
   但这条规则不能省 —— 全局的 .category-name:hover{background:#fbfcfd}（近白）会在悬停时
   把粉底洗成白色，比不做还糟。这里显式保持透明，让标题行的粉底原样透上来。 */
/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-row--enhanced .category-name:hover {
    background: transparent;
  }

  /* 「点击展开 / 点击收起」提示：鼠标落在**整条按钮**任何位置都弹，不再要求瞄准三角。
     气泡本身仍挂在 .category-caret::after 上、位置不变（紧贴它所解释的那个图标）。

     为什么用 CSS 的 :hover 而不是把 JS 的 mouseenter 从 caret 换到按钮上：
     - JS 那套是「加 is-tooltip-visible 类 + 2 秒后自动隐藏」。2 秒是为「三角那么小一块」
       设的；换成整条之后鼠标很容易停超过 2 秒，届时人还在悬停、提示却没了，
       而且不离开再进来就不会再弹。:hover 天然是「停留期间一直显示、离开即消失」。
     - 触屏不匹配 (hover: hover)，所以这条规则在手机上根本不存在 —— 不需要再防模拟 hover 粘住。
     特异性 (0,4,0)，压过 .category-row--enhanced .category-caret::after 的 (0,2,0)
     与基础层 .category-caret::after 的 (0,1,0)，三条属性都由这里决定。
     原先那两条 .is-tooltip-visible 规则已随 JS 一并删除（没有写入方了）。 */
  .category-row--enhanced .category-name:hover .category-caret::after {
    visibility: visible;
    opacity: 1;
    transform: translate(0, 0);
  }
}

/* 三角排在按钮末端（标题在左、三角在右），与上方「成人内容分类」面板的「点击展开 ▶」
   同一形态，也是移动端手风琴的通行惯例。**两个断点一致** —— 2026-09-18 先只在窄屏改，
   站主看过 PC 效果后要求 PC 也照此统一，所以这两条从 640 块提到了基础层。
   三角在 DOM 里是第一个子元素，所以必须用 order 把它排到标题之后；
   只写 margin-left: auto 会把它连同后面的标题一起推到右边。
   它留在 .category-name 按钮**内部**，标出的是「可点收起的区域到哪里为止」。 */
.category-row--enhanced .category-caret {
  width: 25px;
  height: 25px;
  /* margin-right: 8px; */
  order: 2;
  margin-left: auto;
  /* font-size: 30px; */
  /* border-radius: 5px; */
  transform: translateY(-2px);
}

.category-row--enhanced .category-caret-icon {
  display: inline-block;
  transition: transform 0.5s ease;
}

.category-row--enhanced.is-collapsed .category-caret-icon {
  transform: rotate(-90deg);
}

/* 气泡右对齐：三角已经在按钮末端，原来那套居中（left: 50%）或左对齐会把气泡推出面板右缘。
   以三角的右缘为锚、向左生长，两个断点同一套取值。 */
.category-row--enhanced .category-caret::after {
  top: auto;
  right: 0;
  bottom: calc(100% + 8px);
  left: auto;
  transform: translate(0, 3px);
}

/* 三角与「查看更多」之间的竖线。它不是装饰：位置正好落在 .category-name 按钮的右边界与
   本链接的左边界之间，画出来的就是「点这里能收起的区域到哪里为止」。
   颜色沿用标题行下边框的 var(--line)，不新增颜色；.category-heading 是 align-items: stretch，
   所以这条线自然满行高。没有「查看更多」的行不画线 —— 那里本来就没有边界要标
   （zh-hans 38 行里只有 4 行有，en 是全部 29 行）。 */
.category-more-link {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  padding: 10px 16px 10px 10px;
  color: var(--accent-dark);
  font-size: 13px;
  font-weight: 400;
  white-space: nowrap;
  border-left: 1px solid var(--line);
}
.category-more-link:focus-visible {
  outline: 3px solid rgba(214, 51, 108, .28);
  outline-offset: -3px;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-more-link:hover {
    color: var(--hot);
    font-weight: 600;
  }
}

/* 分类标题前的图标，取自左侧面板里同一分类的那一个（面板 data-group-target 与分类行
   data-group 一一对应，zh-hans 38:38、en 29:29 全命中，所以每个标题都拿得到自己的图标）。
   emoji 字形宽高差很多（🎙️ 与 📖 就不一样宽），不装进固定盒子的话 38 行标题的起始位置
   会参差不齐 —— 这也正是面板那份 .category-group-icon 用固定尺寸的原因。
   **刻意不给底板和边框**：标题行本身就带粉底，面板那套
   `border-radius + background: var(--surface-muted)` 圆角底板搬过来看不出任何东西，
   只会白白占掉 2px。（2026-09-21 标题行从纯色 --surface-muted 改成
   --soft-hot → --surface 的渐变之后，图标所在的垂直中点约在 #fff8fb，
   与 --surface-muted 的 #fff4f8 差不到一个色阶 —— 这条结论不受影响。） */
.category-name-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-right: 8px;
  overflow: hidden;
  font-size: 15px;
  line-height: 1;
  text-align: center;
}

/* 分类资源总数紧跟标题。DOM 里它在标题 span 之前，好让标题继续是按钮的
   最后一个 span（折叠和搜索用这个位置读分类名）；order 把它排到标题后面、
   箭头前面。字号和颜色低于标题，不单独占一行。 */
.category-resource-count {
  order: 1;
  flex: 0 0 auto;
  margin-left: 6px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
}

.category-row--enhanced .category-name > span:not([class]) {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.category-name {
  display: flex;
  align-items: center;
  width: 100%;
  margin: 0;
  min-height: 48px;
  padding: 12px 18px;
  color: var(--accent-dark);
  font-size: 15px;
  font-weight: 750;
  text-align: left;
  border: 0;
  border-bottom: 1px solid var(--line);
  -webkit-appearance: none;
  appearance: none;
  background: #fff;
}

/* .category-name::before {
  width: 4px;
  height: 18px;
  margin-right: 9px;
  content: "";
  border-radius: 4px;
  background: var(--accent);
} */

.category-caret {
  position: relative;
  display: inline-grid;
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  margin-left: auto;
  place-items: center;
  color: var(--accent-dark);
  line-height: 0.9;
  /* border: 1px solid #f0c6d5;
  border-radius: 7px; */
  font-size: 32px;
}

.category-caret::after {
  position: absolute;
  z-index: 20;
  top: 50%;
  right: calc(100% + 8px);
  padding: 6px 8px;
  color: #34414d;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  content: attr(data-tooltip);
  visibility: hidden;
  opacity: 0;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: #fff;
  box-shadow: 0 4px 12px rgba(23, 33, 43, .2);
  transform: translate(3px, -50%);
  transition: opacity .14s ease, transform .14s ease, visibility .14s ease;
}

/* 这里原有一条 .category-caret.is-tooltip-visible::after（显示气泡的基础态）。
   2026-09-18 删除：写入这个类的 JS 已经删掉，气泡改由上面那条
   `.category-row--enhanced .category-name:hover .category-caret::after` 负责，
   它自己带全 visibility / opacity / transform 三条，不依赖本规则。 */

.category-row.is-collapsed .category-links {
  height: 0;
  padding-block: 0;
  opacity: 0;
  pointer-events: none;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-name:hover {
    color: var(--hot);
    background: #fbfcfd;
  }
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .category-name:hover .category-caret {
    color: var(--hot);
  }
}

/* 这里曾短暂存在过一条 .category-desc：把 en 那 29 个 .category-row 现成的
   data-description 渲染成分类标题下方可见的一行。2026-09-22 当天加、当天撤。

   **不要再加回来。** 撤销理由是量出来的，不是口味：
     · 29 句里有 3 对几乎重复，其中一对词集完全相同（只差 and / or）；
     · 平均 74 字符、多数占 2 行，29 个分类合计把页面撑高约 1450px ≈ 1.8 屏手机；
     · 内容是「Live Cams & Creators → 覆盖公开摄像头房间、私密场次和创作者直播平台」
       这种把标题换个说法，而英文页真正缺的是**每个站点**的差异
       （Pornhub 与 XVideos 有什么不同），这些段落一个字都没回答。
   导航页的职责是让人快速走掉，为此多滑 1.8 屏是亏的。
   真要补英文页的信息缺口，口子在 data-keywords / 站点级描述，不在分类级文案。

   浮层抑制那一半**保留**了（见 home-directory.js 的 tooltipInfo）—— 那 216 个浮层
   讲的是分类而不是站点，对「在 Pornhub 和 XVideos 之间选一个」毫无帮助，
   与本段落的存废无关。 */

.category-links {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
  min-width: 0;
  overflow: hidden;
  opacity: 1;
  padding: 12px;
  transition: height .5s ease, opacity .5s ease;
  will-change: height, opacity;
}

.site-link {
  position: relative;
  display: flex;
  align-items: center;
  min-width: 0;
  padding: 10px 12px;
  color: #34414d;
  font-size: 13.5px;
  font-weight: 600;
  white-space: nowrap;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease, color .15s ease;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .site-link:hover {
    color: var(--hot);
    border-color: #dfa7bb;
    box-shadow: 0 4px 12px rgba(214, 51, 108, .12);
    transform: translateY(-1px);
  }
}

.site-link-icon {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-right: 8px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: #fff;
}

.site-link span {
  overflow: hidden;
  text-overflow: ellipsis;
}

/* 142 分类批量导入后使用的站点卡片：保留完整简介文本（DOM 中不截断，
   仅视觉上用 line-clamp 收到 3 行，不影响搜索和 SEO）。
   用 .category-links.category-links--cards 复合选择器提高优先级，
   盖过 .category-links 在 900px / 640px 断点里已有的列数规则，
   不需要再为这个新组件单独写响应式断点。 */
.category-links.category-links--cards {
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
  padding: 12px;
}

.site-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 12px 14px;
  color: inherit;
  text-decoration: none;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.site-card:focus-visible {
  border-color: #dfa7bb;
  box-shadow: 0 4px 12px rgba(214, 51, 108, .12);
  transform: translateY(-1px);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .site-card:hover {
    border-color: #dfa7bb;
    box-shadow: 0 4px 12px rgba(214, 51, 108, .12);
    transform: translateY(-1px);
  }
}

.site-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.site-card-icon {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  object-fit: contain;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: #fff;
}

.site-card-name {
  overflow: hidden;
  color: var(--accent-dark);
  font-weight: 700;
  font-size: 14px;
  line-height: 1.3;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: color .15s ease;
}

.site-card:focus-visible .site-card-name {
  color: var(--hot);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .site-card:hover .site-card-name {
    color: var(--hot);
  }
}

.site-card-desc {
  display: -webkit-box;
  overflow: hidden;
  color: var(--muted);
  font-size: 12.5px;
  line-height: 1.45;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  /* 「关闭描述」的 0.5 秒过渡靠这三条，**不能**改用 display 切换 —— display 不可动画，
     而且这里必须保持 -webkit-box，否则上面那条 line-clamp 失效、描述会从 3 行炸成全文。
     max-height 通常的毛病是「内容高度未知只能往大里估、缓动手感失真」，这里不存在：
     clamp 死在 3 行，12.5px × 1.45 × 3 = 54.375px，56 是几乎精确的紧界。
     裁剪依赖上面的 overflow: hidden，别删。塌陷态见 body.hide-card-desc 那条。 */
  max-height: 56px;
  opacity: 1;
  visibility: visible;
  transition: max-height .5s ease-out, opacity .5s ease-out,
              margin-top .5s ease-out, visibility .5s;
}

/* Business service descriptions distinguish merchant billing from broker-arranged
   escrow. Keep the complete explanation visible when descriptions are enabled. */
body:not(.hide-card-desc) #adult-business-services .site-card-desc {
  -webkit-line-clamp: unset;
  max-height: none;
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */

/* 正文与页脚之间的分隔线。
   原先这个位置是「本站分类 / Love8 Sections」那块入口导航，2026-09-16 按站主要求
   换成一条横线，线以下读作页脚。
   注意下面 .footer 的 border-top 是**被注释掉**的 —— 这条线本来就该存在，
   只是位置在页脚容器上时被背景色断开了；挪到这里对齐 .footer-inner 的宽度更干净。
   宽度公式与 .footer-inner 一致，所以线的两端和页脚内容对齐。 */
.home-divider {
  width: 100%;
  margin: 18px auto 14px;
  border: 0;
  border-top: 1px solid var(--line);
}

.footer {
  margin-top: 0px;
  /* border-top: 1px solid var(--line); */
  background: #f4f6f9;
}

.footer-inner {
  width: min(var(--max), calc(100% - 40px));
  margin: 0 auto;
  padding: 0px 0 0px;
  text-align: center;
}

.footer-nav,
.footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 16px;
}

.footer-nav a,
.footer-links a {
  min-height: 36px;
  padding: 7px 13px;
  color: var(--accent-dark);
  font-size: 13px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: rgba(255, 255, 255, .76);
}

/* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
@media (hover: hover) {
  .footer-nav a:hover,
  .footer-links a:hover {
    border-color: var(--hot);
    color: var(--hot);
  }
}

.footer-links {
  margin: 0px auto 0;
  padding: 0px;
  /* border-top: 1px solid #e7ebf0;
  border-bottom: 1px solid #e7ebf0; */
  /* background: rgba(255, 255, 255, .52); */
}

.footer-note,
.footer-disclosure,
.footer-copy {
  max-width: 680px;
  margin-right: auto;
  margin-left: auto;
  color: #34465b;
  font-size: 14px;
  line-height: 1.75;
}

.footer-note {
  margin-top: 14px;
  margin-bottom: 0;
}

.footer-disclosure {
  margin-top: 12px;
  margin-bottom: 0;
}

.footer-copy {
  margin-top: 17px;
  margin-bottom: 0;
  color: #536273;
  font-size: 13px;
}

@media (max-width: 900px) {
  .category-shell {
    grid-template-columns: 200px minmax(0, 1fr);
  }

  .direct-grid {
    grid-template-columns: repeat(var(--shortcut-columns, 5), minmax(0, 1fr));
  }
}

@media (max-width: 640px) {

  .topbar-inner,
  .page {
    width: min(100% - 28px, var(--max));
  }

  .topbar-inner {
    min-height: 58px;
  }

  .brand {
    gap: 8px;
    min-width: 0;
  }

  .brand-text {
    min-width: 0;
  }

  .brand-mark {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    border-radius: 8px;
  }

  .brand-name {
    font-size: 16px;
  }

  .brand-tagline {
    font-size: 11px;
  }

  .top-links {
    flex-shrink: 0;
    gap: 6px;
    font-size: 12px;
  }

  .bookmark-button {
    width: 30px;
    min-height: 28px;
    padding: 3px;
    border-radius: 5px;
  }

  .bookmark-label {
    display: none;
  }

  .bookmark-icon {
    font-size: 17px;
  }

  .bookmark-toast {
    top: calc(100% + 6px);
    max-width: min(250px, calc(100vw - 28px));
  }

  .search-area {
    padding: 2px 0px 5px 0px;
  }

  .search-form {
    --search-button-width: 58px;
    border-radius: 6px;
  }

  .search-input {
    height: 35px;
    padding: 0 41px 0 10px;
    font-size: 14px;
  }

  .search-clear {
    width: 28px;
    height: 28px;
    font-size: 19px;
    line-height: 1;
  }

  .search-button {
    font-size: 14px;
    font-weight: 500;
  }

  .category-shell {
    display: block;
  }

  .category-navigator {
    position: static;
    display: block;
    max-height: none;
    overflow: visible;
    margin: 5px 0 5px;
    /* 必须与上下两块同值：上面是 .direct-grid、下面是 .directory-panel，窄屏都是 6px。
       三者在窄屏是上下堆叠、等宽的一列，圆角不同一眼就看得出来。
       改这里就要连带改下面两处头部圆角（展开态与收起态），它们是由这个值减 1px 边框推出来的。 */
    border-radius: 6px;
    /* 2026-09-21 站主要求全表静态描边统一为 #DDD，这条覆盖也跟着改。
       在此之前它是 #dfa7bb：2026-09-18 站主反馈 var(--line)(#f2dbe3) 压页面底 #f6f7fb 只有
       1.22:1「颜色很淡」，才专门调重到 1.89:1 —— 收起态整块只剩一条标题栏时尤其明显。
       #DDD 是 1.27:1，只比那次投诉时的 1.22 强一点。收起态轮廓若又变难认，这里是第一个该单独调重的地方（等亮度中性灰是 #BBB，1.79:1）。 */
    border-color: var(--line);
  }

  /* 收起态必须裁剪，否则四角会「缺一块」。
     原因是这三件事叠在一起：手机上本容器是 `overflow: visible`（桌面基础层是 hidden）、
     面板有 6px 圆角、而 .category-navigator-header 的渐变背景是**方角**的。
     收起后面板只剩这条标题栏，它的方角背景就直接盖过了圆角，加上描边本来就淡，
     看上去就是四个角缺失。动画过程中同理。 */
  .category-navigator.is-collapsed,
  .category-navigator.is-animating {
    overflow: hidden;
  }

  .category-navigator-header {
    padding: 2px 12px 2px 16px;
    /* 头部必须自己带圆角，不能指望父容器裁剪 —— 展开态的 .category-navigator 是
       `overflow: visible`（为了不切掉卡片投影），而头部的渐变背景是方角的，
       会直接盖住面板顶部那两个 6px 圆角。5px = 外圆角 6px − 1px 边框，正好贴合内边缘。 */
    border-radius: 5px 5px 0 0;
  }

  .category-navigator-header::before {
    top: 11px;
    left: 7px;
  }

  /* 窄屏：标题栏是折叠开关。面板展开时高达 1068px（zh-hans 38 个分类）≈ 1.3 屏，
     默认收起之后只剩这一条标题栏（约 41px），首屏直接是真正的目录内容。 */
  /* 整条标题栏是点击区（44px 是触摸目标的通行下限），不是只有那个三角。 */
  .category-navigator-toggle {
    min-height: 20px;
    cursor: pointer;
    /* 0 而不是基础层的 6px —— 站主反馈「点击展开」与三角之间太空。
       那个三角是 36px 字号的字形，本身左右自带空白（side bearing），
       所以即使 gap 归零，视觉上仍有几像素间隔，这正好是要的效果。
       flex 的 gap 作用于每一对相邻项，标题和右侧文案的间距改由各项自己的 margin 负责。 */
    gap: 0;
  }

  /* 「展开 / 收起」两个字。三角是没有边框也没有底色的裸字形，可点性全靠它自己，
     旁边给两个字是最便宜的补强。刻意不写「点击展开」—— 整条标题栏就是按钮，
     「点击」是废话；而且屏读器那边 aria-label 已经在说完整句子，这两个字是 aria-hidden 的。 */
  .category-navigator-hint {
    display: inline;
    margin-left: auto;
    color: var(--muted);
    font-size: 13px;
    /* font-weight: 600; */
  }

  /* 只把字形放大，不加任何底色/描边。之前 14px 在手机上太小；
     28×28 的粉色圆角块是另一种东西，站主明确不要。
     点击区靠整条标题栏（.category-navigator-toggle 的 min-height）保证，不靠这个字形。
     `margin-left: auto` 现在挂在 .category-navigator-hint 上，两者作为一组靠右。 */
  .category-navigator-caret {
    display: inline-block;
    color: var(--accent-dark);
    font-size: 36px;
    line-height: 1;
    /* 「点击收起 ↔ ▾」的间距。不能改 .category-navigator-toggle 的 gap —— flex 的 gap
       作用于每一对相邻项。gap 归零之后，每一处间距各自负责。 */
    margin-left: 5px;
    /* 必须与 .category-groups-clip 的 height 过渡**逐字相同**（时长 + 缓动），
       否则就会出现「箭头还在转、内容已经没了」或反过来。
       缓动跟随面板取 ease-out，不是反过来：面板那条 ease-out 是有理由的
       （位移前段快、末段缓，掩盖 38 张卡片重排的卡顿），而这里的 ease 没有任何理由。
       CLAUDE.md 记过一次同型事故（面板受 prefers-reduced-motion 保护、箭头没有，
       结果箭头平滑转 0.5 秒而面板瞬变，被误诊两次）。 */
    transition: transform .5s ease-out;
  }

  /* 收起时指向右，与分类行的箭头方向一致。 */
  .category-navigator.is-collapsed .category-navigator-caret {
    transform: rotate(-90deg);
  }

  /* 高度动画放在这层**裁剪层**上，不放在网格本身 —— 这是卡顿的解法。

     原来是直接给 .category-groups（38 张卡片的网格容器）逐帧改 height，于是浏览器每一帧
     都要重排整个网格、再重排它下方的整页内容，手机上明显一顿一顿（站主 2026-09-18 反馈）。
     拆开之后：网格的盒子全程不变（它的内部布局只依赖宽度，宽度没动），每帧只剩这层的高度
     和页面下方要重排。页面下方的重排是躲不掉的 —— 折叠本来就要让出空间。

     ease-out 而不是 ease：位移前段快、末段缓，卡顿更不容易被察觉。 */
  .category-groups-clip {
    display: block;   /* 基础层是 display: contents（桌面端不参与布局） */
    overflow: hidden;
    /* 时长与缓动都必须与 .category-navigator-caret 逐字相同，且与 JS 的 SLIDE_MS 同值。
       这三处曾经各写各的：2026-09-18 试过把时长收到 .28s，但只改了三角，面板和
       SLIDE_MS 都留在 500，于是三角 280ms 转完、面板还要再跑 220ms——站主报的
       「三角先转弯角度」就是这个。2026-09-19 站主定回 .5s，三处一起改。
       缓动同理：同时长不同曲线，中途进度仍然对不上
       （ease-out 在半程已走完 ~80%，ease 才 ~50%），所以三角也跟着取 ease-out。 */
    transition: height .5s ease-out;
    will-change: height;
  }

  /* 窄屏改双列卡片：靠卡片边界分隔，不再用逐条的下划线。
     注意这里**没有任何过渡** —— 网格在动画期间必须保持静止，否则拆分就白拆了。 */
  .category-groups {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    padding: 10px;
    overflow: visible;
  }

  /* 收起态的终值挂在裁剪层上。动画过程中 JS 用内联 height 逐帧覆盖它，结束后清掉内联值，
     由这条兜住最终状态 —— 这样 JS 不必记住「收起时高度该是多少」。
     内距不必再归零：内距属于里面那层网格，而这层 `overflow: hidden` 会把它一起裁掉。 */
  .category-navigator.is-collapsed .category-groups-clip {
    height: 0;
  }

  /* 收起时那条分隔线下面已经什么都没有了，留着就是一条悬空的线。 */
  .category-navigator.is-collapsed .category-navigator-header {
    border-bottom-color: transparent;
    /* 收起后面板只剩这条标题栏，四角都要圆。同样是外圆角 6px − 1px 边框。 */
    border-radius: 5px;
  }

  .category-group-button {
    gap: 8px;
    /* 38px 而不是 46px：隐掉图标之后绝大多数分类名只占一行，而一行按钮的实际内容高度是
       8+16+8 内距行高 + 2 边框 = 34px —— 46px 的下限把省下来的折行白白吃掉了
       （少折 13 行只省 20px）。降到 38px 之后 zh-hans 的分类面板 1044 → 916px、
       en 822 → 702px，各省 120px 上下。仍会折行的少数长标签自己撑到 48px，不受影响。 */
    min-height: 38px;
    padding: 8px 8px 8px 10px;
    font-size: 13px;
    align-items: center;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--surface);
    box-shadow: 0 1px 3px rgba(214, 51, 108, .05);
  }

  /* 卡片模式靠底色和描边表达状态，指示条与分隔线在这里都是多余的。 */
  .category-group-button::before,
  .category-group-button::after {
    display: none;
  }

  /* hover 关在能力查询里：触屏的模拟 hover 会粘住（点完不恢复）。 */
  @media (hover: hover) {
    .category-group-button:hover {
      border-color: #f4b6cb;
    }
  }

  .category-group-button.is-active,
  .category-group-button[aria-current="location"] {
    border-color: var(--hot);
    box-shadow: 0 2px 10px rgba(255, 23, 68, .16);
  }

  /* 2026-09-17 试过在窄屏 `display: none` 掉这些图标：标签可用宽度能从 87.5px 涨到 117.5px、
     折行按钮 16 → 3 个。但站主看过实际效果后判定「UI 不好看」，已恢复。
     不要再以「省空间」为由去掉它们 —— 纵向收益本来就只有约 20px，真正省高度的是
     下面那条 min-height。 */
  .category-group-icon {
    width: 22px;
    height: 22px;
    border-radius: 7px;
    font-size: 12px;
  }

  .category-group-label {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    line-height: 1.25;
  }

  .category-group-chevron {
    font-size: 13px;
  }

  .direct-grid {
    grid-template-columns: repeat(var(--shortcut-columns, 5), minmax(0, 1fr));
    margin: 0;
    padding: 5px 2px;
    border-radius: 6px;
  }

  .direct-site {
    gap: 3px;
    min-height: 62px;
    padding: 5px 1px;
    font-size: 11px;
    line-height: 1.15;
  }

  .direct-favicon {
    width: 30px;
    height: 30px;
    padding: 2px;
    border-radius: 7px;
  }

  /* 窄屏悬浮按钮的位置、颜色和页脚让位在 nav-floating-tools.css。 */

  .directory {
    padding: 0px 0 0px;
  }

  .directory-panel {
    border-radius: 6px;
  }

  .category-name {
    min-height: 39px;
    padding: 5px 5px;
    font-size: 13px;
  }

  .category-more-link {
    padding: 8px 8px;
    font-size: 12px;
  }

  /* 图标跟着标题一起收一档（标题 15px -> 13px，行高 48px -> 39px）。
     图标与文字同号，两者视觉分量才一致。 */
  .category-name-icon {
    width: 18px;
    height: 18px;
    margin-right: 6px;
    font-size: 13px;
  }

  /* 窄屏隐藏分类标题后的资源数量，把宽度还给标题。
     display:none 才会退出 flex；visibility 或把字号收到 0 仍占着那一块。
     数量节点、data-resource-count 和统计逻辑都留在页面里，桌面端继续走基础层。 */
  .category-resource-count {
    display: none;
  }

  /* 数量让位之后，标题在图标和箭头之间换行，不再用省略号截断。
     箭头是 flex: 0 0 auto，查看更多在按钮外面也是 flex: 0 0 auto，
     长标题只会在自己的格子里折行，不会盖住箭头，也不会把右侧链接挤扁。
     margin-inline-end 在 LTR / RTL 都留在标题和箭头之间。 */
  .category-row--enhanced .category-name > span:not([class]) {
    margin-inline-end: 4px;
    overflow: hidden;
    text-overflow: clip;
    white-space: normal;
    overflow-wrap: break-word;
    line-height: 1.3;
  }

  /* .category-name::before {
    width: 3px;
    height: 16px;
    margin-right: 7px;
  } */

  .category-caret {
    /* width: 29px;
    height: 29px; */
    font-size: 30px;
  }

  /* 三角末端对齐、竖线、气泡右对齐这三条原本关在这个块里（窄屏专有），
     2026-09-18 站主要求 PC 与移动端统一，已全部提到基础层，这里不再需要覆盖。 */

  .category-links {
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 6px;
    padding: 8px;
  }

  .site-link {
    padding: 9px 10px;
    font-size: 12.5px;
  }

  /* 卡片在窄屏收成两列小卡，描述保留一行。
     基础层第 973-977 行的注释当初判断「复合选择器已盖过已有断点，不需要再为这个新组件
     单独写响应式断点」—— 那时它是个新组件，判断合理；今天 212 张卡片分布在 38 个分类里，
     375px 下仍跑桌面的 minmax(220px) 恒为 1 列、85% 的卡片撑满 line-clamp:3 的 106px，
     #categories 总高约 23,548px（≈29 屏），实在太长。

     **描述不能整条隐掉。** 先前这里写的是 `display: none`，结果移动端的描述既看不见、
     也弹不出浮层（`home-directory.js` 的 getDescription 对卡片一律早退），等于彻底消失；
     而那个浮层只绑了 mouseenter / focus，真机上点一下就跳走，本来就触发不了。
     所以改成 line-clamp: 1 —— 卡面上留一行，真机用户直接看得到，不依赖任何交互。

     注意选择器必须保留 .category-links.category-links--cards 这个 (0,2,0) 的复合写法 ——
     它要盖过的正是上面第 1568 行的 .category-links (0,1,0)。 */
  .category-links.category-links--cards {
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 6px;
    padding: 8px;
  }

  /* 窄屏：卡片压成胶囊 —— 只留图标 + 站名，描述隐藏。
     188 张卡片按桌面取值渲染时 #categories 高达 ~23,548px（≈29 屏），
     站主确认移动端占 >70% 流量、这批描述属装饰性内容，所以窄屏上把它藏掉，
     尺寸逐项对齐同一块里的 `.site-link` 胶囊，两种形态在窄屏视觉一致。

     描述的文本**留在 DOM 里**，只是 `display: none`：
     · 搜索走 `site.textContent`（home-directory.js），不受影响，按描述搜仍命中；
     · `getDescription()` 读 `.site-card-desc` 的 computed display，发现被隐藏时
       改用卡面文本当浮层内容 —— 所以描述在窄屏是「移进悬停浮层」，不是丢失。

     要回到「卡面显示描述」：把 `display: none` 换成 `-webkit-line-clamp: 1`，
     卡片会从 38px 涨到 70px。 */
  .site-card {
    flex-direction: row;
    align-items: center;
    gap: 0;
    padding: 9px 10px;
  }

  .site-card-icon {
    width: 18px;
    height: 18px;
  }

  .site-card-name {
    font-size: 12.5px;
    font-weight: 600;
  }

  .site-card-desc {
    display: none;
  }

  /* 用户按了「显示描述」：body 上挂 .show-card-desc，把上面那条藏描述的规则顶回去。
     (0,2,0) 压 (0,1,0)，与源顺序无关。取值抄基础层的 .site-card-desc —— 卡片重新变成
     「站名一行 + 描述最多 3 行」，高度从 38px 回到约 106px，这是用户自己换的。
     `-webkit-box` 与 box-orient 必须一起写，否则 line-clamp 不生效、描述会全量展开。 */
  body.show-card-desc .site-card-desc {
    display: -webkit-box;
    -webkit-box-orient: vertical;
  }

  /* 光把描述显示出来是不够的：窄屏的 .site-card 是 `flex-direction: row`（胶囊形态，
     图标+站名排一行），描述一出现就成了横排的第三个弹性项，把带 ellipsis 的站名挤到
     几乎为零 —— 页面上看到的就是「图标压着一段描述、站名不见了」。
     所以开启态必须把卡片整体换回竖排，取值抄基础层（column / gap 4px）。 */
  body.show-card-desc .site-card {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }

  .footer {
    margin-top: 0px;
  }

  .footer-inner {
    width: min(100% - 28px, var(--max));
    padding: 0px 0 0px;
  }

  .footer-nav,
  .footer-links {
    gap: 8px;
  }

  .footer-nav a,
  .footer-links a {
    min-height: 34px;
    padding: 7px 11px;
    font-size: 12px;
  }

  .footer-links {
    margin-top: 0px;
    padding: 0px 8px;
  }

  .footer-note,
  .footer-disclosure,
  .footer-copy {
    font-size: 13px;
    line-height: 1.7;
  }

  .footer-note {
    margin-top: 10px;
  }

  .footer-disclosure {
    margin-top: 10px;
  }

  .footer-copy {
    margin-top: 14px;
    font-size: 12px;
  }

  .other-directory h2 {
    font-size: 16px;
  }
}

/* 极窄手机仍按实际数量排满两行，长品牌名可换行。 */
@media (max-width: 390px) {
  .direct-grid {
    grid-template-columns: repeat(var(--shortcut-columns, 5), minmax(0, 1fr));
  }

  .direct-site {
    min-height: 60px;
  }

  .direct-favicon {
    width: 29px;
    height: 29px;
  }

  /* 极窄屏把箭头让位给分类名，避免 10 字标题被挤成三行。 */
  .category-group-chevron {
    display: none;
  }

  .category-group-button {
    padding-right: 6px;
  }
}
/* 图标槽里装 emoji 而不是 <img> 时的补充规则。

   起因：zh-hans 的 204 张卡与 en 的 209 张卡 100% 指向**外部网站**，所以每张都能取到
   自己的 favicon（google s2/favicons 或 navigation-icons/ 下的本地文件）。而 ja 的 137 张卡
   100% 指向 /ja/ 的**站内文章**，没有等价的逐条图标源，站内文章本来也不该配"网站 logo"。
   那里改用按内容选的 emoji。

   .site-card-icon(:1481) 与 .direct-favicon(:1035) 都是类选择器、不带 img 限定，所以
   <span> 能复用它们的尺寸/边框/白底；但那两条是按替换元素写的，没有 display 也没有居中，
   span 里的 emoji 会贴在左上角。下面两条只补这件事。

   **span. 前缀是 load-bearing 的**：en 与 zh-hans 的这两类图标槽全部是 <img>，
   构造上不可能命中，那两页的层叠输入一个字节都不变。不要改成无标签的 .site-card-icon。 */
span.site-card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 1;
}

span.direct-favicon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  line-height: 1;
}

/* inline-style-classes:begin --- 由 scripts/sync-inline-style-classes.mjs 生成，勿手改 */
.directory-gap-sm,
.directory.directory-gap-sm {
  margin-top: 5px;
}

.home-footnote {
  color: var(--muted);
  font-size: 13px;
  margin-top: 16px;
  text-align: center;
}
/* inline-style-classes:end */
