/* ==========================================================================
   LongPT · Nebula Design System · components.css
   --------------------------------------------------------------------------
   组件层：表格 / 表单 / 按钮 / 徽章 / 提示框 / 分页 / 卡片
   这里是「让页面变好看」的主力层，覆盖审计出的全部历史写法：
     - 1254 处 table / td 表现型属性  → .nx-table / .nx-cell-* 语义类
     -  398 处无 class 表单控件        → 属性选择器兜底 + .nx-input 显式类
     -  166 处 <font color=...>        → .nx-text-* 语义类
   ========================================================================== */

/* ==========================================================================
   1. 表格
   ========================================================================== */

/* 现代表格：默认形态（用于种子列表、用户列表等） */
table.nx-table,
table.torrents,
table.main:not(.nx-raw),
table.table,
table.nx-table-auto {
    width: 100%;
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-radius: var(--nx-radius-lg);
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
    box-shadow: var(--nx-shadow-sm);
    margin: 0 0 var(--nx-space-5);
}

/* 表头 */
table.nx-table > thead > tr > th,
table.torrents > tbody > tr > td.colhead,
table.torrents > tr > td.colhead,
table.nx-table > tbody > tr > td.colhead,
table.nx-table > tr > td.colhead {
    background: var(--nx-surface-sunken);
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: var(--nx-space-4) var(--nx-space-4);
    border: 0;
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
    white-space: nowrap;
    text-align: left;
    position: sticky;
    top: 0;
    z-index: 2;
}

/* 行 */
table.nx-table > tbody > tr,
table.torrents > tbody > tr { transition: background-color var(--nx-dur-fast) var(--nx-ease-out); }

table.nx-table > tbody > tr > td,
table.torrents > tbody > tr > td,
table.nx-table > tr > td,
table.torrents > tr > td {
    padding: var(--nx-space-4);
    border: 0;
    border-bottom: var(--nx-border-thin) solid var(--nx-divider);
    vertical-align: middle;
    color: var(--nx-text);
    line-height: var(--nx-leading-snug);
}

/* ── 行斑马纹叠加层 ──────────────────────────────────────────────────
   刻意做成「半透明中性叠加」而不是实色，两个原因：
   ① 它叠在各主题自己的 surface 之上 → 深色主题自动提亮、浅色主题自动压暗，
      三主题 × 明暗通吃，不必给每个主题单独挑一个条纹色；
   ② 不能复用 `--nx-surface-alt` —— 那个令牌被 17 处「次级面 / 按钮底 / 勋章容器」
      引用，把它调深会牵连全局观感。
   定义放在共享层（而不是各主题 tokens.css）：这两个值三主题完全相同，
   放这儿靠 components.css 的同步机制一次覆盖三主题，省掉 3×3 处重复维护。 */
:root {
    /* 0.055 → 白底上约 #F2F3F5，与 #FFFFFF 差 13/255；再淡（如 0.032）实测只有
       8/255，肉眼「看不出有隔行换色」——这是用户直接反馈过的问题。 */
    --nx-row-stripe: rgba(15, 23, 42, 0.055);
}
[data-nx-theme="dark"] {
    /* 深色下刻意比浅色弱一档：深色主题的条纹和悬停都是「提亮」，
       条纹太强会把悬停色吃掉（实测 0.05 时两者只差 (3,4,9)，几乎分不出）。
       压到 0.04 后条纹仍有 ~9/255 的区分度，同时给悬停让出空间。 */
    --nx-row-stripe: rgba(255, 255, 255, 0.04);
}
@media (prefers-color-scheme: dark) {
    :root:not([data-nx-theme="light"]):not([data-nx-theme="dark"]):not(.nx-force-light) {
        --nx-row-stripe: rgba(255, 255, 255, 0.04);
    }
}

/* 斑马纹 */
table.nx-table > tbody > tr:nth-child(even) > td,
table.torrents > tbody > tr:nth-child(even) > td {
    background-image: linear-gradient(var(--nx-row-stripe), var(--nx-row-stripe));
}

/* ⚠️ 种子列表的「标题列」内部还嵌着第二张表 table.torrentname，它的格子带
   class="embedded"，会被上面通用规则里的 `td.embedded { background: var(--nx-surface) }`
   刷上不透明底色 —— 而斑马纹只作用在 table.torrents 的**直接子** td 上，
   铺到标题列就被这层盖掉。表现就是：分类图标/封面图/种子名那一块
   （截图里用户圈起来的左侧区域）不跟着隔行换色，右侧数字列却正常。
   ⚠️ 注意 `table.torrentname > tbody > tr > td` 的特异性 (0,1,4) 虽然高于
   td.embedded 的 (0,1,1)，但它**没有 background 声明**，所以压不住这里的背景，
   必须单独显式清掉。 */
table.torrents table.torrentname td.embedded {
    background: transparent;
}

/* ── 论坛版块列表（forums.php：「公告区 / 官方邀请区 …」那些小节）─────────────
   ⚠️ 这张表在 PHP 里是裸写的：
        <table border="1" cellspacing="0" cellpadding="5" width="100%">
      —— **没有任何 class**。所以针对 table.torrents / table.nx-table 的规则一条都不命中，
      单元格对齐只剩浏览器默认的 `vertical-align: middle`。
      而「最近回复」列往往有 3~5 行内容、其余列只有 1 行，居中之后各列首行高低不一，
      整行看着「散、错位」。
   用「表头首列 width=99%」这个独一无二的特征把它锁出来（:has 精确匹配，不误伤别的表），
   各列一律改为从顶部对齐，行首就齐了。 */
#outer table:has(> tbody > tr > td.colhead[width="99%"]) > tbody > tr > td {
    vertical-align: top;
}
/* 主题 / 帖子 两个计数列：数字不换行（表头是 center，数字也是 center，正好对住） */
#outer table:has(> tbody > tr > td.colhead[width="99%"]) > tbody > tr > td[width="1%"] {
    white-space: nowrap;
}
/* ⚠️ 表头首列写死了 width="99%"，把「最近回复 / 版主」两列压到只剩几十像素 ——
   后果是「最近回复」里每一行被拆成 3~4 个字就换行、英文单词还会被拦腰截断
   （如 【Officia / l】、seraph...），整列看着像竖排的乱码。
   把首列宽度交还给自动布局（CSS 能覆盖 HTML 的 width 表现属性），
   再给这两列一个能正常阅读的最小宽度。 */
#outer table:has(> tbody > tr > td.colhead[width="99%"]) > tbody > tr > td.colhead[width="99%"] {
    width: auto;
}
#outer table:has(> tbody > tr > td.colhead[width="99%"]) > tbody > tr > td:nth-child(4),
#outer table:has(> tbody > tr > td.colhead[width="99%"]) > tbody > tr > td:nth-child(5) {
    min-width: 104px;
}
/* 悬停 */
table.nx-table > tbody > tr:hover > td,
table.torrents > tbody > tr:hover > td {
    background: var(--nx-surface-hover);
}
/* 最后一行去边框 */
table.nx-table > tbody > tr:last-child > td,
table.torrents > tbody > tr:last-child > td { border-bottom: 0; }

/* ── 老式数据表：隔行换色 + 悬停 ──────────────────────────────────────
   ⚠️ 上面几条只覆盖 table.nx-table / table.torrents，**漏掉了 table.main** ——
   而排行榜（topten.php）、用户列表、日志等老页面用的都是 `begin_table()` 输出的
   `<table class="main">`，症状就是「列表既没有隔行换色，鼠标悬浮也毫无反馈」。

   怎么只挑出「数据表」：要求**表头行里出现两个相邻的 td.colhead**。
   这是数据表独有的特征（表头是整整一行 colhead）。而
     · 表单表每行只有 1 个 colhead（`<td class="colhead">标签</td><td class="rowfollow">输入框</td>`）
     · 布局表连 colhead 都没有
   所以都不会被误伤，不用去枚举 class 名。

   ⚠️ 两个必须的排除项：
   ① `:not(:has(> td.colhead))` 排除表头行。本选择器特异性远高于 `td.colhead` 的 (0,1,1)，
      不排除的话鼠标划过表头会整行变蓝、斑马纹也会染到两行表头的第二行。
   ② 悬停规则排在斑马纹**之后** —— 两者特异性相同，靠源顺序压过条纹，
      否则鼠标划到偶数行时条纹会盖住悬停色（看起来「这行没反应」）。 */
table:has(> tbody > tr > td.colhead + td.colhead) > tbody > tr:nth-child(even):not(:has(> td.colhead)) > td {
    background-image: linear-gradient(var(--nx-row-stripe), var(--nx-row-stripe));
}
table:has(> tbody > tr > td.colhead + td.colhead) > tbody > tr:hover:not(:has(> td.colhead)) > td {
    background: var(--nx-surface-hover);
}
table:has(> tbody > tr > td.colhead + td.colhead) > tbody > tr:last-child > td {
    border-bottom: 0;
}
/* 数据表里常嵌着小表（榜单的国旗格就是 `<table class="main"><td class="embedded">`），
   而 `td.embedded` 全局是不透明白底，会把所在行的条纹盖出一个白块
   —— 同 table.torrents 里 torrentname 的处理思路，在这类上下文里让它透明。 */
table:has(> tbody > tr > td.colhead + td.colhead) td.embedded {
    background: transparent;
}

/* 兼容老式 td 类名（审计显示大量使用 rowhead / rowfollow） */
td.rowhead {
    background: var(--nx-surface-sunken);
    color: var(--nx-text-secondary);
    font-weight: var(--nx-weight-semibold);
    padding: var(--nx-space-4);
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
}
td.rowhead_center { text-align: center; }
td.rowhead_left { text-align: left; }

/* 信息 / 表单类表格的标签列：老代码把它写死成 width="1%"
   （用户中心的信息表最典型，且那张表没有 class，theme.css 里
   限定 table.main 的规则匹配不上）。宽屏下 1% 只剩十几 px，
   中文标签被压成逐字竖排。定宽 + nowrap 让标签列稳定可读。 */
td.rowhead[width="1%"] {
    width: 150px !important;
    min-width: 150px;
    white-space: nowrap;
}

/* 表头一律不换行。老站表头多为短词或图标，一旦所在列被压窄，
   中文表头会逐字竖排（如「发布者」→ 发/布/者、「回复/查看」被拆两行）。
   注意 table.torrents 的表头上面已单独处理过，这里是给其它表格兜底。 */
td.colhead { white-space: nowrap; }

/* ══════════════════════════════════════════════════════════════════════════
   种子列表表头精修（table.torrents 的 td.colhead）
   ──────────────────────────────────────────────────────────────────────────
   原来表头只有「sunken 底 + 小字 + secondary 色」，用户反馈「想美化一下」。
   实际看下来是三个问题：
     ① 图标列被内容撑得很宽，6 个排序图标之间空荡荡、很散；
     ② 「标题 / 发布者」是可排序链接，但长得和普通文字一样，没有可点暗示；
     ③ text-transform: uppercase 对中文无影响，却会把英文表头变成全大写。
   ⚠️ 图标来自 styles/sprites.css，是**写死尺寸 + background-position 的 sprite**，
      绝不能改 width/height（会整块错位）—— 只能动 opacity / transform / 对齐。
   ══════════════════════════════════════════════════════════════════════════ */

/* ① 图标列收窄并居中：让排序图标聚拢，不再被撑开 */
table.torrents > tbody > tr > td.colhead:has(> a > img) {
    width: 1%;
    text-align: center;
}

/* ② 表头里的可排序链接。
      种子表这批 <a> 没有 colheadlink 类，所以按结构直接命中
      （「标题」列是纯文字链接，「图标」列是 a>img，两者都该有可点反馈）。 */
table.torrents > tbody > tr > td.colhead > a {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-1, 4px);
    padding: var(--nx-space-1, 4px) var(--nx-space-2, 8px);
    margin: calc(var(--nx-space-1, 4px) * -1) calc(var(--nx-space-2, 8px) * -1);
    color: var(--nx-text);
    font-weight: var(--nx-weight-bold);
    letter-spacing: 0.02em;
    border-radius: var(--nx-radius-sm, 4px);
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
}
table.torrents > tbody > tr > td.colhead > a:hover {
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
    text-decoration: none;
}

/* ③ 排序图标：hover 提亮 + 微放大（scale 不参与布局，安全） */
table.torrents > tbody > tr > td.colhead > a > img {
    opacity: 0.7;
    transition: opacity var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
table.torrents > tbody > tr > td.colhead > a:hover > img {
    opacity: 1;
    transform: scale(1.15);
}

/* ══════════════════════════════════════════════════════════════════════════
   表头排序图标：把老式 sprite 换成**现代线性图标**（2026-09-20）
   ──────────────────────────────────────────────────────────────────────────
   这些是 `<img class="comments|time|size|seeders|leechers|snatched"
   src="pic/trans.gif">`，图形来自 styles/sprites.css 的 icons.gif sprite
   （16px 位图，深色底上发灰、边缘发毛）。

   这里用 **mask + background-color** 覆盖：
     · mask 决定形状（内联 SVG，任意缩放不糊）
     · background-color 决定颜色（用令牌 → **跟随主题与明暗**）
   比直接塞一张彩色 background-image 更合适：能跟着主题变色。

   ⚠️ 用 `table.torrents img.xxx` 提高特异性，确保盖过 sprites.css 的
      `img.xxx`（两者原本同级，谁后加载谁赢，不可靠）。
   ⚠️ 尺寸保持 16px 不变，避免撑动表头高度。
   ══════════════════════════════════════════════════════════════════════════ */

/* 统一的 mask 基础属性 */
table.torrents img.comments,
table.torrents img.time,
table.torrents img.size,
table.torrents img.seeders,
table.torrents img.leechers,
table.torrents img.snatched {
    background-color: var(--nx-text-secondary);
    background-image: none;               /* 盖掉 sprite 图 */
    -webkit-mask-repeat: no-repeat;
            mask-repeat: no-repeat;
    -webkit-mask-position: center;
            mask-position: center;
    -webkit-mask-size: contain;
            mask-size: contain;
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out);
}

/* ① 评论数 —— 对话气泡 */
table.torrents img.comments {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z'/></svg>");
}

/* ② 添加时间 —— 时钟 */
table.torrents img.time {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9.5'/><polyline points='12 6.5 12 12 16 14.5'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='9.5'/><polyline points='12 6.5 12 12 16 14.5'/></svg>");
}

/* ③ 大小 —— 立方体包裹 */
table.torrents img.size {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'/><polyline points='3.3 7 12 12 20.7 7'/><line x1='12' y1='22' x2='12' y2='12'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'/><polyline points='3.3 7 12 12 20.7 7'/><line x1='12' y1='22' x2='12' y2='12'/></svg>");
}

/* ④ 做种数 —— 上箭头（保留绿色语义） */
table.torrents img.seeders {
    background-color: var(--nx-success-text, #34d399);
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><line x1='12' y1='19.5' x2='12' y2='5'/><polyline points='5.5 11.5 12 5 18.5 11.5'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><line x1='12' y1='19.5' x2='12' y2='5'/><polyline points='5.5 11.5 12 5 18.5 11.5'/></svg>");
}

/* ⑤ 下载数 —— 下箭头（保留红色语义） */
table.torrents img.leechers {
    background-color: var(--nx-danger-text, #f87171);
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><line x1='12' y1='4.5' x2='12' y2='19'/><polyline points='18.5 12.5 12 19 5.5 12.5'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><line x1='12' y1='4.5' x2='12' y2='19'/><polyline points='18.5 12.5 12 19 5.5 12.5'/></svg>");
}

/* ⑥ 完成数 —— 对勾 */
table.torrents img.snatched {
    background-color: var(--nx-success-text, #34d399);
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6.5 9.5 17 4 11.5'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><polyline points='20 6.5 9.5 17 4 11.5'/></svg>");
}

/* hover 时表头图标提到正文色 */
table.torrents > tbody > tr > td.colhead > a:hover > img.comments,
table.torrents > tbody > tr > td.colhead > a:hover > img.time,
table.torrents > tbody > tr > td.colhead > a:hover > img.size {
    background-color: var(--nx-primary-strong);
}

/* ④ 表头整体：背景提亮 + 列分隔 + 关掉无意义的全大写。
      ⚠️ `--nx-surface-sunken` 在深色主题下与页面底几乎同色，表头会「融」进内容区
         （截图确认过）。这里叠一层主色微染把它「托」出来 ——
         用两层 background 而不是 color-mix()，兼容性更稳。 */
table.torrents > tbody > tr > td.colhead {
    background:
        linear-gradient(var(--nx-primary-soft, transparent), var(--nx-primary-soft, transparent)),
        var(--nx-surface-sunken);
    text-transform: none;
    color: var(--nx-text);
    border-bottom: var(--nx-border-thin) solid var(--nx-border-strong, var(--nx-border));
    /* 列分隔用 inset 阴影做：不占盒模型、不会让列宽跳动 */
    box-shadow: inset 1px 0 0 0 var(--nx-divider, var(--nx-border));
}
table.torrents > tbody > tr > td.colhead:first-child {
    box-shadow: none;
}
td.rowfollow {
    padding: var(--nx-space-4);
    border-bottom: var(--nx-border-thin) solid var(--nx-divider);
    vertical-align: middle;
}
td.embedded {
    background: var(--nx-surface);
    border: 0;
    padding: var(--nx-space-5);
    border-radius: var(--nx-radius-lg);
}
td.colfollow {
    padding: var(--nx-space-3) var(--nx-space-4);
    border-bottom: var(--nx-border-thin) solid var(--nx-divider);
}

/* 对齐辅助类（替换 align="center" 等属性） */
.nx-center { text-align: center !important; }
.nx-left   { text-align: left !important; }
.nx-right  { text-align: right !important; }
.nx-middle { vertical-align: middle !important; }
.nx-top    { vertical-align: top !important; }
.nx-bottom { vertical-align: bottom !important; }
.nx-nowrap { white-space: nowrap !important; }
.nx-w-full { width: 100% !important; }
.nx-w-auto { width: auto !important; }

/* 宽度阶梯（替换 width="60" 这类魔数） */
.nx-w-xs  { width: 48px !important; }
.nx-w-sm  { width: 72px !important; }
.nx-w-md  { width: 110px !important; }
.nx-w-lg  { width: 160px !important; }
.nx-w-xl  { width: 220px !important; }

/* 促销行底纹（保留原有 .free_bg / .twoup_bg 等类名，重做配色） */
.free_bg,
tr.free_bg > td { background: var(--nx-promo-free-bg) !important; }
.twoup_bg,
tr.twoup_bg > td { background: var(--nx-promo-2x-bg) !important; }
.twoupfree_bg,
tr.twoupfree_bg > td { background: var(--nx-promo-2xfree-bg) !important; }
.halfdown_bg,
tr.halfdown_bg > td { background: var(--nx-promo-halfdown-bg) !important; }
.thirtypercent_bg,
tr.thirtypercent_bg > td { background: var(--nx-promo-50-bg) !important; }
.thirtypercentdown_bg,
tr.thirtypercentdown_bg > td { background: var(--nx-promo-2x50-bg) !important; }
.twouphalfdown_bg,
tr.twouphalfdown_bg > td { background: var(--nx-promo-2xhalfdown-bg) !important; }
.transparentbg { background: transparent !important; }

/* ── 促销徽章 .nx-promo ─────────────────────────────────────────────────
   取代 styles/icons.gif 顶部那条 36×11 的雪碧图。旧图的问题不只是难看：
   颜色烧死在位图里（明暗都不变）、放大即糊、写的是英文（换语言也不变），
   而且 11px 高的一长条压在 14px 正文里，基线永远对不齐。
   functions.php:5522 的 icon 分支现在输出
   `<span class="nx-promo pro_50pctdown">50%</span>`，文案沿用「文字」模式那批
   lang 键，所以这里只负责形状和配色。

   ⚠️ 刻意不加 transition：色值全部来自 --nx-* 变量，主题切换时带过渡会踩
      「变量色不重算」那一类问题（同 nexus.css 里图标那段的说明）。
   ⚠️ 修饰符写成 `.nx-promo.pro_xxx`（0-2-0）：只写 `.pro_xxx` 会和别的
      组件同名时打架，且这里是在覆盖 .nx-promo 自己声明的自定义属性。 */
.nx-promo {
    --nx-promo-c:    var(--nx-text-secondary);
    --nx-promo-c-bg: var(--nx-surface-sunken);
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 1px var(--nx-space-2);
    border-radius: var(--nx-radius-sm);
    background: var(--nx-promo-c-bg);
    color: var(--nx-promo-c);
    font-size: var(--nx-font-xs);
    font-weight: var(--nx-weight-bold);
    line-height: 1.55;
    letter-spacing: .02em;
    white-space: nowrap;
    vertical-align: middle;
}
/* FAQ 的「新 / 更新」标记（2026-09-22）——
   原来是 icons.gif 里 40×11 的**文字图**（位图上直接画着 NEW / UPDATED 字样）：
   位图在高分屏会糊，而且它本来就是文字，没必要做成图。改成真正的文字胶囊，
   复用上面的 .nx-promo，只覆盖两个颜色变量。
   标记本身仍在 faq.php 里（<img> 挂不了伪元素，只能换元素）。 */
.nx-promo.nx-promo-new     { --nx-promo-c: var(--nx-primary-strong); --nx-promo-c-bg: var(--nx-primary-soft); }
.nx-promo.nx-promo-updated { --nx-promo-c: var(--nx-warning-text);   --nx-promo-c-bg: var(--nx-warning-soft); }

/* 前缀箭头把「谁变多、谁变少」写进图形里：光看 "2X" / "50%" 得先记住哪个是上传。
   箭头用 ::before 生成，不进 DOM，所以复制标题时不会跟着带出来。 */
.nx-promo::before { font-weight: var(--nx-weight-bold); }
.nx-promo.pro_free::before,
.nx-promo.pro_50pctdown::before,
.nx-promo.pro_30pctdown::before { content: "↓"; }
.nx-promo.pro_2up::before { content: "↑"; }
.nx-promo.pro_free2up::before,
.nx-promo.pro_50pctdown2up::before { content: "↑↓"; }

.nx-promo.pro_free        { --nx-promo-c: var(--nx-promo-free);       --nx-promo-c-bg: var(--nx-promo-free-bg); }
.nx-promo.pro_2up         { --nx-promo-c: var(--nx-promo-2x);         --nx-promo-c-bg: var(--nx-promo-2x-bg); }
.nx-promo.pro_free2up     { --nx-promo-c: var(--nx-promo-2xfree);     --nx-promo-c-bg: var(--nx-promo-2xfree-bg); }
.nx-promo.pro_50pctdown   { --nx-promo-c: var(--nx-promo-halfdown);   --nx-promo-c-bg: var(--nx-promo-halfdown-bg); }
.nx-promo.pro_50pctdown2up { --nx-promo-c: var(--nx-promo-2xhalfdown); --nx-promo-c-bg: var(--nx-promo-2xhalfdown-bg); }
.nx-promo.pro_30pctdown   { --nx-promo-c: var(--nx-promo-30);         --nx-promo-c-bg: var(--nx-promo-30-bg); }

/* ==========================================================================
   2. 表单
   ========================================================================== */

/* 文本类输入框：显式类 */
.nx-input,
.nx-textarea,
.nx-select,
.layer-form input[type="text"],
.layer-form input[type="password"],
.layer-form textarea,
.layer-form select {
    width: 100%;
    max-width: 100%;
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-base);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-inset);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
    appearance: none;
    -webkit-appearance: none;
}
.nx-input:hover,
.nx-textarea:hover,
.nx-select:hover { border-color: var(--nx-text-tertiary); }

.nx-input:focus,
.nx-textarea:focus,
.nx-select:focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
    background: var(--nx-surface);
}

.nx-input:disabled,
.nx-input[readonly],
.nx-textarea:disabled,
.nx-select:disabled {
    background: var(--nx-surface-sunken);
    color: var(--nx-text-disabled);
    cursor: not-allowed;
    box-shadow: none;
}

.nx-input::placeholder,
.nx-textarea::placeholder { color: var(--nx-text-tertiary); opacity: 1; }

.nx-textarea { min-height: 96px; resize: vertical; }

/* select 下拉箭头（自定义，替代浏览器默认） */
.nx-select {
    padding-right: var(--nx-space-8);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%2364748b' d='M6 8.5L1.5 4h9z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--nx-space-3) center;
    cursor: pointer;
}

/* 兜底：给没有 class 的历史控件一个基本体面（审计出 398 处） */
.form-box input[type="text"]:not([class]),
.form-box input[type="password"]:not([class]),
.form-box input[type="number"]:not([class]),
.form-box select:not([class]),
.form-box textarea:not([class]),
/* 2026-09-18：兜底选择器原先只列了 text / password，导致 input[type=number]
   （体积范围 / 做种人数范围 / 下载人数范围 …）完全没样式，在深色主题下渲染成一块黑底。
   改为「排除按钮/复选/单选/文件/隐藏」的宽松写法，以后新增类型也不会再漏。 */
#outer input:not([class]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]),
#outer textarea:not([class]) {
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-base);
    color: var(--nx-text);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-inset);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
#outer input:not([class]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="hidden"]):focus,
#outer textarea:not([class]):focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}

/* 复选框 / 单选 */
.nx-checkbox,
.nx-radio,
input[type="checkbox"],
input[type="radio"] {
    width: 16px;
    height: 16px;
    accent-color: var(--nx-primary);
    cursor: pointer;
    vertical-align: middle;
    margin: 0 var(--nx-space-2) 0 0;
}

/* 表单行布局 */
.form-box { padding: var(--nx-space-5); }
.form-control-row {
    display: flex;
    align-items: center;
    gap: var(--nx-space-4);
    padding: var(--nx-space-4) 0;
    border-bottom: var(--nx-border-thin) solid var(--nx-border-subtle);
}
.form-control-row:last-child { border-bottom: 0; }
.form-control-row .label {
    flex: 0 0 auto;
    width: 130px;
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
}
.form-control-row .field { flex: 1 1 auto; min-width: 0; }
.form-control-row .field input[type="text"],
.form-control-row .field input[type="password"],
.form-control-row .field textarea { width: 100%; }

/* ==========================================================================
   3. 按钮
   ========================================================================== */
/* ⚠️ 这里的 :not() 排除列表是必要的，不是洁癖：
   下面这条「全局 button 美化」会给【页面里每一个 <button>】加上
   底色 / 描边 / 圆角 / 阴影，而第三方控件（如 jquery-datetimepicker 的
   翻页箭头）用的是「纯雪碧图按钮」——它们没有文字、只有 background-position，
   被套上圆角+底色后会显示成一块常驻的深色药丸，把图标糊掉。
   ⇒ 凡是在第三方 widget 内部、靠背景图当图标的按钮，都要加进排除列表。

   ⚠️ 2026-09-20 追加 `:not([class*="nx-ts-"])`：这条规则的特异度是 (0,1,1)
   （button + :not 里的属性选择器），比组件自己写的单类选择器 `.nx-ts-scheme` (0,1,0) 高，
   于是「界面外观」面板的四类按钮（触发钮 / 配色项 / 模式项 / 恢复默认）被整条顶掉：
   display:grid 变回 inline-flex + justify-content:center ⇒ 色块按每行文字宽度居中，
   实测四个色块左缘错开 459/470/481/470（差 22px）；padding 8/16 顶掉 4/8；
   border-radius 10 顶掉 --nx-radius-full ⇒ 圆形触发钮变成方角；background:transparent
   顶掉成 --nx-surface ⇒ 未选中的配色项也画成一张实心卡。
   结论：凡是自带盒模型的组件按钮，一律用 `nx-ts-` 这类前缀挂进排除列表，
   别靠「把组件规则写在后面」——同特异度才轮到源码顺序，这里根本不同级。

   ⚠️ 2026-09-27 追加排除项 `nx-rp-`：拆封动效那只圆形的「开」
   （.nx-rp-open-btn）自带盒模型 —— 被这条套上 padding/圆角/白底后，
   76px 的金色圆章会变成一块白色方角牌（实测截图里按钮整个走形）。
   同一段注释里已经说过：别指望「把组件规则写在后面」，同特异度才轮到源码顺序。
   🔴 但排除项必须写成【一个 :not() 里逗号并列】而不是链式 `:not():not()`：
   链式写法每多一个 :not 就多一层类特异度，三个就是 (0,3,1)，
   会把 `button.nx-btn.nx-btn-primary`（0,2,1）连同 danger / ghost 变体全站压掉
   —— 主按钮变成白底（实测拆红包按钮 background 从 #1677ff 退回 #fff）。
   `:not(a, b, c)` 只取最具体那个参数的特异度 ⇒ 整条停在 (0,2,1)，变体照常赢。 */
button:not([class*="xdsoft"], [class*="nx-ts-"], [class*="nx-rp-"]),
input[type="submit"],
input[type="button"],
input[type="reset"],
.nx-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-5);
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    cursor: pointer;
    text-align: center;
    white-space: nowrap;
    box-shadow: var(--nx-shadow-xs);
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out),
                color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
button:not([class*="xdsoft"], [class*="nx-ts-"], [class*="nx-rp-"]):hover,
input[type="submit"]:hover,
input[type="button"]:hover,
.nx-btn:hover {
    background: var(--nx-surface-hover);
    border-color: var(--nx-primary);
    color: var(--nx-primary-strong);
    box-shadow: var(--nx-shadow-sm);
}
button:not([class*="xdsoft"], [class*="nx-ts-"], [class*="nx-rp-"]):active,
input[type="submit"]:active,
.nx-btn:active { transform: translateY(1px); box-shadow: var(--nx-shadow-xs); }
button:not([class*="xdsoft"], [class*="nx-ts-"], [class*="nx-rp-"]):disabled,
input[type="submit"]:disabled,
input[type="button"]:disabled,
.nx-btn:disabled { opacity: 0.55; cursor: not-allowed; transform: none; }

/* 主按钮 */
/* ⚠️ 必须把 input[type=...] 和 button 一起点名：上面那条基础规则是
   `input[type="button"]` 与 `button:not([class*="xdsoft"]):not([class*="nx-ts-"])`
   （都是 (0,1,1) / (0,2,1)），单挂一个 `.nx-btn-primary` 类（0,1,0）特异度更低会被顶掉 ——
   任务页的「领取」是 input[type=button]，红包页的「拆红包」是 <button>，
   只写类名的话主色永远上不去了（实测按钮停在基础档的白底 + 6px 圆角）。
   button 那一支要写两级类：`button.nx-btn-primary` 只有 (0,1,1)，压不住 (0,2,1) 的
   基础规则；`button.nx-btn.nx-btn-primary` 是 (0,2,1) + 源码在后才赢。
   forums.php 那个只挂 `.nx-btn-primary` 的搜索按钮是有意走基础长相的
   （见 nexus.css:969），不在这一支里，别去动它。 */
.nx-btn-primary,
button.nx-btn.nx-btn-primary,
input[type="submit"].nx-btn-primary,
input[type="button"].nx-btn-primary {
    background: var(--nx-primary);
    border-color: var(--nx-primary);
    color: var(--nx-on-primary);
    box-shadow: var(--nx-shadow-sm);
}
.nx-btn-primary:hover,
button.nx-btn.nx-btn-primary:hover,
input[type="submit"].nx-btn-primary:hover,
input[type="button"].nx-btn-primary:hover {
    background: var(--nx-primary-hover);
    border-color: var(--nx-primary-hover);
    color: var(--nx-on-primary);
    box-shadow: var(--nx-shadow-md);
}

/* 次要 / 危险 / 幽灵（button 同样要点名，理由见上） */
.nx-btn-danger,
button.nx-btn.nx-btn-danger { background: var(--nx-danger); border-color: var(--nx-danger); color: #fff; }
.nx-btn-danger:hover,
button.nx-btn.nx-btn-danger:hover { background: var(--nx-danger-text); border-color: var(--nx-danger-text); color: #fff; }
.nx-btn-ghost,
button.nx-btn.nx-btn-ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--nx-text-secondary); }
.nx-btn-ghost:hover,
button.nx-btn.nx-btn-ghost:hover { background: var(--nx-primary-soft); color: var(--nx-primary-strong); box-shadow: none; }
/* 同上：任务页「已领取」是 input[type=button].nx-btn-ghost，不点名就还是实心白按钮 */
input[type="button"].nx-btn-ghost,
input[type="submit"].nx-btn-ghost { background: transparent; border-color: var(--nx-border); box-shadow: none; color: var(--nx-text-tertiary); }
input[type="button"].nx-btn-ghost:hover,
input[type="submit"].nx-btn-ghost:hover { background: transparent; color: var(--nx-text-tertiary); box-shadow: none; transform: none; }
.nx-btn-sm { padding: var(--nx-space-2) var(--nx-space-3); font-size: var(--nx-font-sm); }
.nx-btn-lg { padding: var(--nx-space-4) var(--nx-space-7); font-size: var(--nx-font-lg); }

/* ---- 标签测试表单（tags.php，2026-09-21）----
   老标记形如：
     <textarea name=test cols=60 rows=3></textarea>
     <input type=submit style="height:23px; margin-left:5px" value=测试标签!>
   两个都是行内元素 → 挤在同一行；按钮又带**内联** height:23px（内联压过一切，
   基础按钮规则那套 38px 高度全被压掉），于是看起来像贴在输入框右下角的一颗小药丸。
   现在：竖排 + 输入框占一行 + 按钮用主按钮样式（内联样式已在标记里去掉了）。 */
.nx-tag-test {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--nx-space-3);
    margin: var(--nx-space-3) 0 var(--nx-space-5);
}
.nx-tag-test > textarea {
    width: 100%;
    max-width: 720px;                        /* 不铺满整卡，读起来更舒服 */
    box-sizing: border-box;
    min-height: 76px;
}

/* ---- 「是否在线」状态点（staff.php，2026-09-21）----
   老标记是 sprite：<img class="button_online|button_offline" src="pic/trans.gif">，
   视觉全部来自 sprites.css 里 icons.gif 的格子 —— 两张图几乎分不出谁在线，
   而且都偏红，跟设计系统也搭不上。
   现在改成语义化的状态点：
     在线 = 绿点 + 一圈向外扩散淡出的光环（心跳感，1.6s 一轮）
     离线 = 灰点（静态、低存在感）
   ⚠️ <img> 是替换元素、**不能挂伪元素** → 心跳只能用 box-shadow 扩散做，不能用 ::after 光环。
   ⚠️ sprites.css 在 stdhead 的 css 列表**末尾**（晚于本文件加载）→ 同特异性会盖住这里，
      所以下面几条关键声明带 !important。老主题(2/3/4/6/7/8)加载不到本文件，保持原 sprite 不变。 */
img.button_online,
img.button_offline {
    width: 10px !important;                  /* sprites.css 在本文件之后加载、且同特异性，不加 !important 会被它压回 15px */
    height: 10px !important;
    max-width: none !important;              /* 否则被全局 img{max-width:100%} 压扁 */
    border-radius: 50%;
    display: inline-block;
    vertical-align: middle;
}
img.button_online {
    background: var(--nx-success) !important;   /* shorthand 同时清掉 sprite 的 background-image */
    animation: nx-staff-online-pulse 1.6s var(--nx-ease-in-out) infinite;
}
img.button_offline {
    background: var(--nx-text-disabled) !important;
}
/* 心跳：一圈同色光环从圆点边缘向外扩散并淡出 */
@keyframes nx-staff-online-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(63, 185, 80, 0.55); }
    70%  { box-shadow: 0 0 0 7px rgba(63, 185, 80, 0); }
    100% { box-shadow: 0 0 0 0 rgba(63, 185, 80, 0); }
}
@media (prefers-reduced-motion: reduce) {
    img.button_online { animation: none; box-shadow: none; }
}

/* 兼容历史 .btn / .btn2 / .gobutton */
.btn, .btn2 {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--nx-space-3) var(--nx-space-5);
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
    background: var(--nx-surface);
    color: var(--nx-text);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-xs);
    transition: all var(--nx-dur-fast) var(--nx-ease-out);
}
.btn:hover, .btn2:hover {
    background: var(--nx-primary);
    border-color: var(--nx-primary);
    color: var(--nx-on-primary);
    box-shadow: var(--nx-shadow-sm);
}
.gobutton {
    display: inline-flex;
    align-items: center;
    padding: var(--nx-space-2) var(--nx-space-4);
    font-size: var(--nx-font-sm);
    background: var(--nx-primary);
    color: var(--nx-on-primary);
    border: 0;
    border-radius: var(--nx-radius-md);
    cursor: pointer;
}

/* ==========================================================================
   4. 徽章 / 标签
   ========================================================================== */
.nx-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-1);
    padding: 2px var(--nx-space-3);
    font-size: var(--nx-font-xs);
    font-weight: var(--nx-weight-semibold);
    line-height: 1.7;
    border-radius: var(--nx-radius-full);
    border: var(--nx-border-thin) solid transparent;
    white-space: nowrap;
}
.nx-badge-primary { background: var(--nx-primary-soft); color: var(--nx-primary-strong); border-color: var(--nx-primary-border); }
.nx-badge-success { background: var(--nx-success-soft); color: var(--nx-success-text); border-color: var(--nx-success-border); }
.nx-badge-warning { background: var(--nx-warning-soft); color: var(--nx-warning-text); border-color: var(--nx-warning-border); }
.nx-badge-danger  { background: var(--nx-danger-soft);  color: var(--nx-danger-text);  border-color: var(--nx-danger-border); }
.nx-badge-info    { background: var(--nx-info-soft);    color: var(--nx-info-text);    border-color: var(--nx-info-border); }
.nx-badge-neutral { background: var(--nx-surface-sunken); color: var(--nx-text-secondary); border-color: var(--nx-border); }

/* ==========================================================================
   5. 文字语义色（替换 <font color="...">）
   ========================================================================== */
.nx-text        { color: var(--nx-text); }
.nx-text-muted  { color: var(--nx-text-tertiary); }
.nx-text-secondary { color: var(--nx-text-secondary); }
.nx-text-primary { color: var(--nx-primary-strong); }
.nx-text-success { color: var(--nx-success-text); }
.nx-text-warning { color: var(--nx-warning-text); }
.nx-text-danger  { color: var(--nx-danger-text); }
.nx-text-info    { color: var(--nx-info-text); }
.nx-text-bold    { font-weight: var(--nx-weight-semibold); }
.nx-text-sm      { font-size: var(--nx-font-sm); }
.nx-text-xs      { font-size: var(--nx-font-xs); }
.nx-text-lg      { font-size: var(--nx-font-lg); }

/* 兼容历史语义类（保留类名，重做配色） */
.red    { color: var(--nx-danger-text) !important; }
.green  { color: var(--nx-success-text) !important; }
.yellow { color: var(--nx-warning-text) !important; }
.gray   { color: var(--nx-text-tertiary) !important; }
.important { color: var(--nx-danger-text) !important; font-weight: var(--nx-weight-semibold); }
.free   { color: var(--nx-promo-free) !important; font-weight: var(--nx-weight-semibold); }
/* 「文字」模式（functions.php:5495 的 word 分支）输出 `<b>[<font class='twoup'>…`。
   原来这里只给了 .free 和 .hot 上色，剩下五个促销类没人管，切到文字模式时
   [2X] / [50%] 会退回正文色，和同一行的 [免费] 明显不是一个东西。 */
.twoup           { color: var(--nx-promo-2x) !important; font-weight: var(--nx-weight-semibold); }
.twoupfree       { color: var(--nx-promo-2xfree) !important; font-weight: var(--nx-weight-semibold); }
.halfdown        { color: var(--nx-promo-halfdown) !important; font-weight: var(--nx-weight-semibold); }
.twouphalfdown   { color: var(--nx-promo-2xhalfdown) !important; font-weight: var(--nx-weight-semibold); }
.thirtypercent   { color: var(--nx-promo-30) !important; font-weight: var(--nx-weight-semibold); }
.hot    { color: var(--nx-promo-50) !important; font-weight: var(--nx-weight-bold); }
.classic{ color: var(--nx-info-text) !important; }
.new    { color: var(--nx-danger-text) !important; font-weight: var(--nx-weight-bold); }
.striking { color: var(--nx-warning-text) !important; font-weight: var(--nx-weight-bold); }
.recommended { color: var(--nx-success-text) !important; font-weight: var(--nx-weight-semibold); }
.small  { font-size: var(--nx-font-sm); color: var(--nx-text-secondary); }
.big    { font-size: var(--nx-font-lg); font-weight: var(--nx-weight-semibold); }
.medium { font-size: var(--nx-font-base); }
.text-muted { color: var(--nx-text-tertiary) !important; }

/* 用户等级配色（16 个等级，统一到 token） */
.User_Name, .Peasant_Name        { color: var(--nx-rank-peasant); font-weight: var(--nx-weight-semibold); }
.PowerUser_Name                  { color: var(--nx-rank-power); font-weight: var(--nx-weight-semibold); }
.EliteUser_Name                  { color: var(--nx-rank-elite); font-weight: var(--nx-weight-semibold); }
.CrazyUser_Name                  { color: var(--nx-rank-crazy); font-weight: var(--nx-weight-semibold); }
.InsaneUser_Name                 { color: var(--nx-rank-insane); font-weight: var(--nx-weight-semibold); }
.VeteranUser_Name                { color: var(--nx-rank-veteran); font-weight: var(--nx-weight-semibold); }
.ExtremeUser_Name                { color: var(--nx-rank-extreme); font-weight: var(--nx-weight-semibold); }
.UltimateUser_Name               { color: var(--nx-rank-ultimate); font-weight: var(--nx-weight-semibold); }
.NexusMaster_Name, .NexusMaster  { color: var(--nx-rank-nexus); font-weight: var(--nx-weight-bold); }
.VIP_Name                        { color: var(--nx-rank-vip); font-weight: var(--nx-weight-semibold); }
.Uploader_Name                   { color: var(--nx-rank-uploader); font-weight: var(--nx-weight-semibold); }
.Moderator_Name, .ForumModerator_Name { color: var(--nx-rank-moderator); font-weight: var(--nx-weight-semibold); }
.Administrator_Name              { color: var(--nx-rank-admin); font-weight: var(--nx-weight-bold); }
.SysOp_Name, .StaffLeader_Name   { color: var(--nx-rank-sysop); font-weight: var(--nx-weight-bold); }
.Retiree_Name                    { color: var(--nx-rank-retiree); font-weight: var(--nx-weight-medium); }

/* 用户信息里的语义色标（保留类名） */
.color_bonus       { color: var(--nx-warning-text) !important; font-weight: var(--nx-weight-semibold); }
.color_ratio       { color: var(--nx-primary-strong) !important; font-weight: var(--nx-weight-semibold); }
.color_uploaded    { color: var(--nx-success-text) !important; font-weight: var(--nx-weight-semibold); }
.color_downloaded  { color: var(--nx-danger-text) !important; font-weight: var(--nx-weight-semibold); }
.color_active      { color: var(--nx-info-text) !important; font-weight: var(--nx-weight-semibold); }
.color_connectable { color: var(--nx-text-secondary) !important; font-weight: var(--nx-weight-semibold); }
.color_invite      { color: var(--nx-rank-ultimate) !important; font-weight: var(--nx-weight-semibold); }
.color_slots       { color: var(--nx-text-tertiary) !important; }

/* ==========================================================================
   6. 提示框（msgalert / 系统消息）
   ========================================================================== */
.msgalert,
.nx-alert {
    display: flex;
    align-items: flex-start;
    gap: var(--nx-space-3);
    padding: var(--nx-space-4) var(--nx-space-5);
    margin: 0 0 var(--nx-space-4);
    font-size: var(--nx-font-base);
    line-height: var(--nx-leading-snug);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-left: 3px solid var(--nx-text-tertiary);
    border-radius: var(--nx-radius-lg);
    background: var(--nx-surface);
    color: var(--nx-text);
    box-shadow: var(--nx-shadow-xs);
}
.nx-alert-success, .msgalert.green   { background: var(--nx-success-soft); border-color: var(--nx-success-border); border-left-color: var(--nx-success); color: var(--nx-success-text); }
.nx-alert-warning, .msgalert.orange  { background: var(--nx-warning-soft); border-color: var(--nx-warning-border); border-left-color: var(--nx-warning); color: var(--nx-warning-text); }
.nx-alert-danger,  .msgalert.darkred,
.msgalert.red                        { background: var(--nx-danger-soft);  border-color: var(--nx-danger-border);  border-left-color: var(--nx-danger);  color: var(--nx-danger-text); }
.nx-alert-info,    .msgalert.blue    { background: var(--nx-info-soft);    border-color: var(--nx-info-border);    border-left-color: var(--nx-info);    color: var(--nx-info-text); }
/* 灰/黑两档：msgalert() 的老调用方（未下载提示、被封客户端警告）传的就是这两个颜色名。
   它们本没有语义，只是「中性/次要」，落到灰底灰字，不再用硬编码 #000 压白字。 */
.msgalert.gray, .msgalert.black      { background: var(--nx-surface-sunken); border-color: var(--nx-border); border-left-color: var(--nx-text-disabled); color: var(--nx-text-secondary); }

/* ---- msgalert() 专用（2026-09-22 起从「内联 background + <font color=white>」改为此结构）
   老代码整条是加粗白字；现在字重收到 medium，色调由上面的变体给出。 --------- */
.msgalert {
    display: block;   /* 内容是整句提示（sqlerr 还带 <h1>），排成一行反而会被挤扁 */
    font-weight: var(--nx-weight-medium);
}
.msgalert b { font-weight: var(--nx-weight-semibold); }
/* 通知条里的链接就是唯一的入口，跟着底色走、只靠下划线区分，避免红条上冒出蓝链 */
.msgalert a, .nx-alert a {
    color: inherit;
    font-weight: var(--nx-weight-semibold);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.msgalert a:hover, .nx-alert a:hover { text-decoration: none; }
/* 无 CSS 时（sqlerr 可能在 stdhead 之前发生）也要能读，所以这些标记留在这里兜底 */
.msgalert h1 { margin: 0 0 var(--nx-space-1); font-size: var(--nx-font-lg); }
.msgalert p  { margin: var(--nx-space-1) 0 0; }

/* ==========================================================================
   7. 帮助 / 说明文本（原大量 <font color="..."> + 表格）
   ========================================================================== */
.nx-help {
    padding: var(--nx-space-4) var(--nx-space-5);
    background: var(--nx-surface-sunken);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
    line-height: var(--nx-leading-normal);
}

/* 折叠/剧透 */
.spoiler-title {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-4);
    font-weight: var(--nx-weight-semibold);
    font-size: var(--nx-font-base);
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
    border: var(--nx-border-thin) solid var(--nx-primary-border);
    border-radius: var(--nx-radius-md);
    cursor: pointer;
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out);
}
.spoiler-title:hover { background: var(--nx-surface-hover); }
.spoiler-content { display: inline-block; height: 0; overflow: hidden; transition: height var(--nx-dur-slow) var(--nx-ease-out); }

/* 代码块 */
.codemain, .codetop {
    background: var(--nx-surface-sunken);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    overflow: hidden;
}
.codetop {
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text-secondary);
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg) var(--nx-radius-lg) 0 0;
}
.codemain > pre {
    margin: 0;
    padding: var(--nx-space-4);
    overflow-x: auto;
    background: transparent;
    line-height: var(--nx-leading-snug);
}

/* ==========================================================================
   8. 卡片与容器
   ========================================================================== */
.nx-card {
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-radius: var(--nx-radius-xl);
    box-shadow: var(--nx-shadow-sm);
    padding: var(--nx-space-5);
    margin-bottom: var(--nx-space-5);
}
.nx-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--nx-space-4);
    padding-bottom: var(--nx-space-4);
    margin-bottom: var(--nx-space-4);
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
    font-size: var(--nx-font-lg);
    font-weight: var(--nx-weight-semibold);
}

/* 区块标题（h2 在页面中大量用作分区标题） */
#outer h2,
.outer h2,
h2.nx-section {
    display: flex;
    align-items: center;
    gap: var(--nx-space-3);
    margin: var(--nx-space-6) 0 var(--nx-space-4);
    padding: 0 0 var(--nx-space-3) var(--nx-space-3);
    font-size: var(--nx-font-xl);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text);
    line-height: var(--nx-leading-tight);
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
    /* 原先用主色，但页面里链接、按钮、激活态也全是主色，
       竖线跟着一起亮会显得「颜色重叠」、层次不清。
       改用中性描边色，只承担分隔作用。 */
    border-left: 3px solid var(--nx-border-strong);
}
#outer h2:first-child, .outer h2:first-child { margin-top: 0; }

/* h2 里包裹的辅助链接（老写法：[<a class="altlink">发布</a>]）—— 降级为小号次要按钮 */
#outer h2 font.small,
#outer h2 .small {
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-normal);
    color: var(--nx-text-tertiary);
}
#outer h2 a.altlink {
    color: var(--nx-primary-strong);
    font-weight: var(--nx-weight-medium);
}
#outer h2 a.altlink:hover { color: var(--nx-link-hover); text-decoration: underline; }

/* ==========================================================================
   8b. 无 class 的裸 <table> —— 上古「内联 background 通知条」
   ==========================================================================
   站点大量出现这类结构（审计出的 table-attr / cell-attr 主要就来自它们）：
     <table border="0" cellspacing="0" cellpadding="10"><tr>
       <td style="border:none; padding:10px; background: blue">
         <b><a href="..."><font color="white">&nbsp;&nbsp;有1条新管理组信息&nbsp;&nbsp;</font></a></b>
       </td></tr></table>
   深蓝底 + 白字 + 一串 &nbsp; 撑宽，在窄屏会退化成一条突兀的空蓝条。
   这里统一收成「浅色通知条」，并让内联的 background/color 失效。
   ========================================================================== */
#outer > table:not([class]),
#outer > form > table:not([class]),
#outer > center > table:not([class]),
#outer td.embedded > table:not([class]) {
    width: 100%;
    margin: 0 0 var(--nx-space-3);
    border: 0;
    border-spacing: 0;
    border-radius: var(--nx-radius-lg);
    overflow: hidden;
}
/* 只处理「单行单列」的通知条，避免误伤真正的数据表。
   老写法：<table border="0" cellpadding="10"><tr><td style='...background: blue'>，
   内层 td 无 class。
   ⚠ td 必须加 :not([class]) —— 原选择器只限定到 td:only-child，
   而「最近消息 / 趣味盒」的正文容器是 <td class="text"> 且同样只有一行，
   于是被一并命中，每个区块左侧多出一条蓝色竖线（与 h2 的竖线叠成两条）。 */
#outer > table:not([class]) > tbody > tr:only-child > td:only-child:not([class]),
#outer td.embedded > table:not([class]) > tbody > tr:only-child > td:only-child:not([class]) {
    padding: var(--nx-space-3) var(--nx-space-5) !important;
    background: var(--nx-primary-soft) !important;
    border: var(--nx-border-thin) solid var(--nx-border) !important;
    border-left: 3px solid var(--nx-primary) !important;
    border-radius: var(--nx-radius-lg);
    text-align: left;
    font-size: var(--nx-font-base);
    line-height: var(--nx-leading-normal);
    color: var(--nx-text) !important;
}
/* 内联 font color="white" 在浅底上会消失，强制继承 */
#outer > table:not([class]) > tbody > tr:only-child > td:only-child:not([class]) font,
#outer td.embedded > table:not([class]) > tbody > tr:only-child > td:only-child:not([class]) font,
#outer > table:not([class]) > tbody > tr:only-child > td:only-child b {
    color: inherit !important;
    font-weight: var(--nx-weight-medium) !important;
}
#outer > table:not([class]) > tbody > tr:only-child > td:only-child a {
    color: var(--nx-link) !important;
    font-weight: var(--nx-weight-semibold);
}
#outer > table:not([class]) > tbody > tr:only-child > td:only-child a:hover {
    color: var(--nx-link-hover) !important;
    text-decoration: underline;
}
/* 干掉老代码用来撑宽度的那串 &nbsp; */
#outer > table:not([class]) > tbody > tr:only-child > td:only-child font { white-space: normal; }

/* 孤立的 <br /> 后紧跟下一个块，去掉多余空行 */
#outer > br:only-child { display: none; }

/* ==========================================================================
   8c. 内嵌 iframe（趣味盒 fun.php / 群聊区 shoutbox.php）
   ==========================================================================
   老写法：<iframe src="fun.php?action=view" width='100%' height='300' frameborder='0'>
   裸 iframe 在浅色卡片里显得像个空洞，这里收成圆角内嵌面板。
   ========================================================================== */
#outer iframe {
    display: block;
    width: 100%;
    max-width: 100%;
    border: var(--nx-border-thin) solid var(--nx-card-border) !important;
    border-radius: var(--nx-radius-lg);
    background: var(--nx-surface);
    box-shadow: var(--nx-shadow-inset);
}
#iframe-shout-box { height: 220px; }
iframe[name="funbox"] { height: 300px; }

/* 趣味盒投票行（100个用户… 你觉得呢？[有趣][无聊]）—— 排成一行 */
#funvote {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--nx-space-2);
    margin-top: var(--nx-space-3);
    font-size: var(--nx-font-base);
    color: var(--nx-text-secondary);
}
#funvote input[type="button"],
#funvote .btn { margin: 0; }

/* 群聊区输入行（老写法用 style="display:flex"，这里补全对齐与间距） */
#outer form[name="shbox"] > div {
    display: flex;
    align-items: center;
    gap: var(--nx-space-3);
    margin-top: var(--nx-space-3);
}
#outer form[name="shbox"] > div > label { flex: 0 0 auto; white-space: nowrap; color: var(--nx-text-secondary); }
#outer form[name="shbox"] input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
    border: var(--nx-border-thin) solid var(--nx-border-strong) !important;
}
#outer form[name="shbox"] input[type="submit"] { flex: 0 0 auto; margin: 0; }

/* ==========================================================================
   8e. 悬浮预览大图（勋章 / 封面等 img.preview 的放大预览）
   ==========================================================================
   老结构：<img id="nexus-preview" style="display:none;position:absolute">
   由 nexus.js 在 mouseover/mousemove 时定位到鼠标附近显示。

   ⚠️ BUG：它没有 pointer-events:none，而它又是 absolute 跟着鼠标走的 ——
   图一淡入就盖住了鼠标，于是立刻触发缩略图的 mouseout → hide()，
   鼠标又"回到"缩略图 → mouseover → 再显示…… 来回抖成高频闪烁。
   让它不接收指针事件，鼠标事件穿透过去，闪烁即消失。
   ========================================================================== */
#nexus-preview {
    pointer-events: none;
    /* ⚠️ 层级必须高于吸顶导航（--nx-z-sticky: 200），否则预览图会被
       导航条/信息条盖住顶部。它本质是「跟随光标的浮层提示」，
       按语义用 --nx-z-popover(1100)。原先误用了 --nx-z-dropdown(100)。 */
    z-index: var(--nx-z-popover);
    /* 2026-09-18：悬浮勋章/封面时预览大图会「撑出屏幕」——nexus.js 的
       getImgPosition() 按「鼠标到屏幕边缘的距离」算尺寸，一旦图片
       naturalWidth 还没就绪（算出 0 / NaN）或鼠标贴近边缘，约束就会失效，
       于是按原图尺寸显示（勋章原图常有 500px+）。
       这里加一层 CSS 兜底约束，顺便给圆角与投影，让它像个正经的预览浮层。 */
    max-width: min(56vw, 480px);
    max-height: 68vh;
    /* ⚠️ JS 会内联设置 width/height（按「鼠标到边缘」算的，常常比例失真），
       这里让 CSS 接管：auto + max-* 让它按【原始比例】缩放到范围内，不变形。 */
    width: auto !important;
    height: auto !important;
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-xl);
    background: var(--nx-surface);
}

/* ==========================================================================
   8d. 种子列表：分类图标 + 封面图（2026-09-18）
   ==========================================================================
   分类图标：老代码是
     <img class="c_anime" src="pic/cattrans.gif"
          style="background-image:url(pic/category/.../catsprites.png)">
   靠 img.c_xxx 的 45×46 框 + background-position 取 sprites 的一格。

   ⚠️ 尺寸/定位定义来自 icon 包自带的 CSS，而不是 styles/ 下的文件：stdhead() 会按
      当前页面需要的 search box 动态输出（include/functions.php:2685-2698）
          <link rel="stylesheet" href="{caticons.cssfile}{$cssupdatedate}">
      本站 caticons.cssfile = pic/category/chd/scenetorrents/catsprites.css（该文件存在）。
   ⚠️ 那段输出包在 if ($CURUSER) 里 —— 未登录时整包 CSS 不加载，img.c_xxx 就没有
      width/height/background-position，会退化成「整张 sprites 图的一角」。
      下面只是种子列表首列的兜底尺寸与圆角，不替代那份 CSS。

   封面图：老结构是内嵌 .torrentname 表的第一格，46×46 硬裁。
   ========================================================================== */
table.torrents td:first-child img[class^="c_"] {
    /* ⚠️ 关键：分类图标靠 sprites 的 background-position 定位，
       width/height 必须严格保持 45×46。而 base.css 的全局
       `img{max-width:100%}` 会按列宽把它压扁（探针实测被压到 24.7px，
       height 仍是 46 → 宽高比崩掉），于是 background-position 对不上，
       只露出 sprites 图的一角 —— 这就是「图标显示不全」的真因。 */
    max-width: none;
    width: 45px;
    height: 46px;
    flex-shrink: 0;
    border-radius: var(--nx-radius-md);
    transition: transform var(--nx-dur-base) var(--nx-ease-out),
                box-shadow var(--nx-dur-base) var(--nx-ease-out);
}
table.torrents tr:hover td:first-child img[class^="c_"] {
    transform: translateY(-1px) scale(1.06);
    box-shadow: var(--nx-shadow-md);
}

/* 封面图：统一圆角 + 阴影；悬浮整行时轻微放大，海报能看清一点，
   幅度控制在不会顶乱布局的范围。 */
table.torrentname > tbody > tr > td:first-child img {
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-sm);
    transition: transform var(--nx-dur-slow) var(--nx-ease-out),
                box-shadow var(--nx-dur-slow) var(--nx-ease-out);
}
table.torrents tr:hover table.torrentname > tbody > tr > td:first-child img {
    transform: scale(1.25);
    box-shadow: var(--nx-shadow-lg);
}

/* ⚠️ 表格为了做圆角设了 overflow:hidden，会把放大的封面裁掉 ——
   鼠标进入表格时放开，让放大动画能完整显示（无溢出时视觉无变化）。 */
table.torrents:hover { overflow: visible; }

/* ==========================================================================
   8d. 新闻 / 公告正文（管理员用富文本手写的内容）
   ==========================================================================
   真实写法是四层嵌套：<div align=center><font size="5"><b><span style="color:#...">
   颜色是作者的设计意图，保留；但 font size 用的是老 HTML 字号（1~7），
   在 13px 基线下比例严重失调，这里重映射到设计令牌的字号阶梯。
   ========================================================================== */
#outer font[size="1"] { font-size: var(--nx-font-xs); }
#outer font[size="2"] { font-size: var(--nx-font-sm); }
#outer font[size="3"] { font-size: var(--nx-font-base); }
#outer font[size="4"] { font-size: var(--nx-font-md); }
#outer font[size="5"] { font-size: var(--nx-font-lg); }
#outer font[size="6"] { font-size: var(--nx-font-xl); }
#outer font[size="7"] { font-size: var(--nx-font-2xl); }

/* 新闻折叠块：标题行做成可点击的轻量条 */
#outer td.text > div[style*="margin-left"] { margin-left: 0 !important; }
#outer a[href*="klappe_news"] {
    display: flex;
    align-items: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-4);
    background: var(--nx-surface-sunken);
    border-radius: var(--nx-radius-md);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text);
}
#outer a[href*="klappe_news"]:hover { background: var(--nx-primary-soft); color: var(--nx-primary-strong); }
#outer a[href*="klappe_news"] img { opacity: 0.6; }

/* 新闻正文容器：把 <div align=center> + <br> 造成的「双倍空行」收紧 */
#outer div[id^="ka"] { padding: var(--nx-space-4) var(--nx-space-3) 0; }
#outer div[id^="ka"] > br { display: none; }
#outer div[id^="ka"] > div { margin-bottom: var(--nx-space-2); }
#outer div[id^="ka"] > div:last-child { margin-bottom: 0; }
#outer div[id^="ka"] > div:empty { display: none; }

/* 新闻正文里的分隔线（作者用 ━ 字符画的）—— 降低对比度，别喧宾夺主 */
#outer div[id^="ka"] span[style*="color"] {
    word-break: break-word;
}

/* 通用标题层级收敛 */
#outer h1, .outer h1 { font-size: var(--nx-font-2xl); font-weight: var(--nx-weight-bold); margin: 0 0 var(--nx-space-4); }
#outer h3, .outer h3 { font-size: var(--nx-font-lg); font-weight: var(--nx-weight-semibold); margin: var(--nx-space-5) 0 var(--nx-space-3); }

/* ==========================================================================
   9. 分页
   ========================================================================== */
.nx-pager,
table.nx-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--nx-space-2);
    margin: var(--nx-space-5) 0;
    padding: 0;
    border: 0;
    background: transparent;
    box-shadow: none;
}
.nx-pager a,
.nx-pager span,
table.nx-pager td a,
table.nx-pager td span {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 34px;
    height: 34px;
    padding: 0 var(--nx-space-3);
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text-secondary);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    transition: all var(--nx-dur-fast) var(--nx-ease-out);
}
.nx-pager a:hover,
table.nx-pager td a:hover {
    color: var(--nx-primary-strong);
    border-color: var(--nx-primary);
    background: var(--nx-primary-soft);
}
.nx-pager span.current,
.nx-pager .current,
table.nx-pager td.current {
    color: var(--nx-on-primary);
    background: var(--nx-primary);
    border-color: var(--nx-primary);
    font-weight: var(--nx-weight-semibold);
}

/* ==========================================================================
   10. 工具类
   ========================================================================== */
.nx-mt-0 { margin-top: 0 !important; }
.nx-mt-2 { margin-top: var(--nx-space-2) !important; }
.nx-mt-3 { margin-top: var(--nx-space-3) !important; }
.nx-mt-4 { margin-top: var(--nx-space-4) !important; }
.nx-mt-5 { margin-top: var(--nx-space-5) !important; }
.nx-mb-0 { margin-bottom: 0 !important; }
.nx-mb-3 { margin-bottom: var(--nx-space-3) !important; }
.nx-mb-4 { margin-bottom: var(--nx-space-4) !important; }
.nx-mb-5 { margin-bottom: var(--nx-space-5) !important; }
.nx-p-0  { padding: 0 !important; }
.nx-p-4  { padding: var(--nx-space-4) !important; }
.nx-p-5  { padding: var(--nx-space-5) !important; }
.nx-flex { display: flex !important; }
.nx-flex-col { flex-direction: column !important; }
.nx-items-center { align-items: center !important; }
.nx-justify-between { justify-content: space-between !important; }
.nx-gap-2 { gap: var(--nx-space-2) !important; }
.nx-gap-3 { gap: var(--nx-space-3) !important; }
.nx-gap-4 { gap: var(--nx-space-4) !important; }
.nx-hidden { display: none !important; }
.nx-block { display: block !important; }
.nx-border-0 { border: 0 !important; }
.nx-bg-none { background: none !important; }
.nx-shadow-0 { box-shadow: none !important; }

/* 分隔线（替换裸 <hr>） */
hr,
.nx-divider {
    height: 1px;
    margin: var(--nx-space-5) 0;
    border: 0;
    background: var(--nx-divider);
}

/* ==========================================================================
   10.5 站点四类高频元素补齐
   --------------------------------------------------------------------------
   依据 .workbuddy/tools/scan-classes.php 的真实统计补齐，不是凭空造的。
   全站标签频次：td 2258 / input 1242 / tr 900 / a 667 / table 325 /
                 font 322 / select 134 / li 120 / ul 32 / th 30
   ========================================================================== */

/* ---------------------------------------------------------------------------
   A. 按钮（btn 使用 84 次，是绝对主力；另有 toolbox 容器 36 次）
   --------------------------------------------------------------------------- */

/* toolbox：表单底部的按钮条，老写法 <td class="toolbox" align="center"> */
td.toolbox,
.toolbox {
    padding: var(--nx-space-5) !important;
    background: var(--nx-surface-sunken);
    border-top: var(--nx-border-thin) solid var(--nx-border) !important;
    text-align: center;
}
td.toolbox > *,
.toolbox > * { margin: 0 var(--nx-space-1); }
td.toolbox .btn,
.toolbox .btn { margin: 0 var(--nx-space-1); }

/* .btn 已是主色按钮（见第 3 节），这里补齐它作为 td/容器直接子元素时的对齐 */
.btn { vertical-align: middle; }

/* 勋章/种子盒等操作按钮（.medal-*-btn / .remove-seed-box-btn 等） */
.medal-action-btn,
.medal-action-btn-unified,
.medal-search-btn,
.medal-reset-btn,
.remove-seed-box-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-5);
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-on-primary);
    background: var(--nx-primary);
    border: var(--nx-border-thin) solid var(--nx-primary);
    border-radius: var(--nx-radius-md);
    cursor: pointer;
    box-shadow: var(--nx-shadow-sm);
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
.medal-action-btn:hover,
.medal-action-btn-unified:hover,
.medal-search-btn:hover,
.medal-reset-btn:hover,
.remove-seed-box-btn:hover {
    background: var(--nx-primary-hover);
    border-color: var(--nx-primary-hover);
    box-shadow: var(--nx-shadow-md);
}
.medal-action-btn:active,
.remove-seed-box-btn:active { transform: translateY(1px); }

/* ---------------------------------------------------------------------------
   B. 超链接（a 标签 667 处；faqlink 30 / altlink 29 / colheadlink 8）
   --------------------------------------------------------------------------- */

/* 基态已在 base.css 定义，这里补站点特有三类 */

/* faqlink：管理页 h1 里的面包屑式大标题链接 */
a.faqlink,
.faqlink {
    color: var(--nx-primary-strong);
    font-weight: var(--nx-weight-semibold);
    text-decoration: none;
    border-bottom: 2px solid transparent;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
a.faqlink:hover,
.faqlink:hover {
    color: var(--nx-primary-strong-hover);
    border-bottom-color: var(--nx-primary);
}

/* altlink：正文内的次要操作链接（编辑/删除/禁止 等） */
a.altlink {
    color: var(--nx-primary-strong);
    text-decoration: none;
    padding: 1px var(--nx-space-1);
    border-radius: var(--nx-radius-sm);
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                color var(--nx-dur-fast) var(--nx-ease-out);
}
a.altlink:hover {
    color: var(--nx-primary-strong-hover);
    background: var(--nx-primary-soft);
    text-decoration: underline;
}

/* colheadlink：表头里的可排序链接 —— 必须在浅色表头底上保持清晰 */
a.colheadlink,
.colheadlink {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-1);
    color: var(--nx-text-secondary);
    font-weight: var(--nx-weight-semibold);
    text-decoration: none;
    padding: var(--nx-space-1) var(--nx-space-2);
    border-radius: var(--nx-radius-sm);
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
}
a.colheadlink:hover,
.colheadlink:hover {
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
}

/* 排序箭头指示（表头排序用的 ↑↓） */
a.colheadlink img,
.colheadlink img { opacity: 0.7; }

/* ---------------------------------------------------------------------------
   C. 表格（已有 colhead 620 / rowfollow 365 / rowhead 228 / colfollow 140）
   --------------------------------------------------------------------------- */

/* tablea / tableb / tabletitle：老主题的表格式样，统一收进卡片 */
table.tablea,
table.tableb {
    width: 100%;
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-radius: var(--nx-radius-lg);
    border-collapse: separate;
    border-spacing: 0;
    box-shadow: var(--nx-shadow-sm);
    overflow: hidden;
    margin-bottom: var(--nx-space-5);
}
table.tablea > tbody > tr > td,
table.tableb > tbody > tr > td {
    padding: var(--nx-space-4);
    border-bottom: var(--nx-border-thin) solid var(--nx-divider);
}
table.tablea > tbody > tr:last-child > td,
table.tableb > tbody > tr:last-child > td { border-bottom: 0; }
table.tabletitle {
    background: var(--nx-surface-sunken);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text-secondary);
}

/* search_table：搜索结果表 */
table.search_table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    border-radius: var(--nx-radius-lg);
    overflow: hidden;
    box-shadow: var(--nx-shadow-sm);
}

/* 表格内的复选框（checkbox 22 次） */
input.checkbox,
input[type="checkbox"].checkbox {
    width: 15px;
    height: 15px;
    margin: 0 var(--nx-space-1) 0 0;
    accent-color: var(--nx-primary);
    cursor: pointer;
    vertical-align: -2px;
}

/* ---------------------------------------------------------------------------
   D. 列表（ul 32 / ol 2 / li 120；站点主要用 table 模拟，这里补真列表）
   --------------------------------------------------------------------------- */

#outer ul,
#outer ol {
    margin: 0 0 var(--nx-space-4);
    padding-left: var(--nx-space-7);
    line-height: var(--nx-leading-loose);
    color: var(--nx-text);
}
#outer ul { list-style: disc; }
#outer ol { list-style: decimal; }
#outer ul ul { list-style: circle; margin-bottom: 0; }
#outer ol ol { list-style: lower-alpha; margin-bottom: 0; }
#outer li { margin-bottom: var(--nx-space-2); }
#outer li:last-child { margin-bottom: 0; }
#outer li::marker { color: var(--nx-primary-strong); }

/* 无标记的紧凑列表（导航/工具栏常用） */
#outer ul.nx-plain,
#outer ul[style*="list-style: none"],
#outer ul[style*="list-style:none"] {
    list-style: none;
    padding-left: 0;
    margin-bottom: var(--nx-space-3);
}
#outer ul.nx-plain > li { margin-bottom: var(--nx-space-1); }

/* 定义列表（ol 只有 2 次，但 dl/dt/dd 在帮助/说明页出现） */
#outer dl { margin: 0 0 var(--nx-space-4); }
#outer dt {
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text);
    margin-top: var(--nx-space-3);
}
#outer dt:first-child { margin-top: 0; }
#outer dd {
    margin: var(--nx-space-1) 0 0 var(--nx-space-5);
    color: var(--nx-text-secondary);
    line-height: var(--nx-leading-loose);
}

/* detail-item / detail-label：详情页条目（各 12 次，medal.php 等） */
.detail-item {
    display: flex;
    align-items: flex-start;
    gap: var(--nx-space-3);
    padding: var(--nx-space-3) var(--nx-space-4);
    margin-bottom: var(--nx-space-2);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
.detail-item:hover {
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-sm);
}
.detail-label {
    flex: 0 0 auto;
    min-width: 96px;
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
}

/* dropmenu：隐藏的下拉面板（<div class="dropmenu" style="display:none"><ul>） */
.dropmenu {
    position: absolute;
    z-index: var(--nx-z-dropdown);
    min-width: 180px;
    margin-top: var(--nx-space-1);
    padding: var(--nx-space-2);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-lg);
}
.dropmenu ul { list-style: none; margin: 0; padding: 0; }
.dropmenu li { margin: 0; }
.dropmenu li a {
    display: flex;
    align-items: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-4);
    color: var(--nx-text);
    border-radius: var(--nx-radius-md);
    font-size: var(--nx-font-base);
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                color var(--nx-dur-fast) var(--nx-ease-out);
}
.dropmenu li a:hover {
    background: var(--nx-primary-soft);
    color: var(--nx-primary-strong);
}

/* ---------------------------------------------------------------------------
   E. 补充容器：fieldset / legend（表单分组，此前完全无覆盖）
   --------------------------------------------------------------------------- */
#outer fieldset {
    margin: 0 0 var(--nx-space-5);
    padding: var(--nx-space-5);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-xs);
}
#outer legend {
    padding: var(--nx-space-1) var(--nx-space-4);
    font-size: var(--nx-font-md);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
    border-radius: var(--nx-radius-full);
}

/* ---------------------------------------------------------------------------
   F. 性别 / 状态图标（male / female / no_gender 各 6 次）
      老主题用 sprite 背景图，这里只保证尺寸和对齐不被压变形
   --------------------------------------------------------------------------- */
img.male, img.female, img.no_gender {
    display: inline-block;
    width: 16px;
    height: 16px;
    vertical-align: -3px;
    background-repeat: no-repeat;
    border-radius: var(--nx-radius-sm);
}

/* ---------------------------------------------------------------------------
   G. med / icon / mp 小工具类
   --------------------------------------------------------------------------- */
select.med { width: auto; min-width: 100px; }
img.icon,
.icon { vertical-align: middle; }

/* mp：makepoll.php 的投票输入项（21 次，<input name=option0 class=mp maxlength=40>）
   因为带了 class，:not([class]) 的兜底规则对它无效，这里显式接管 */
#outer input.mp,
#outer input[type="text"].mp,
input.mp {
    width: 100%;
    max-width: 480px;
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-base);
    color: var(--nx-text);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-inset);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
#outer input.mp:focus,
input.mp:focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
#outer input.mp:hover,
input.mp:hover { border-color: var(--nx-primary); }

/* ==========================================================================
   10.6 种子列表筛选下拉框（.med）—— 用户反馈「下拉框颜色看不清晰」
   --------------------------------------------------------------------------
   真实写法：
     <select class="med" name="incldead" style="width: 100px;">
       <option value="0">全部</option> ...
   问题：老主题下 option 背景跟随系统，浅色主题上文字与底色对比不足。
   修法：显式给 option 指定「浅底深字」，并让选中项高亮。
   ========================================================================== */
select.med,
#outer select.med,
/* 老代码里还有大量【没挂 class】的裸 select（torrents.php 搜索区的
   「范围 / 匹配模式」下拉、functions.php 里几处表单下拉都是），
   只覆盖 .med 会漏掉它们 —— 显示成系统默认外观，也就是用户说的「太素」。
   这里把同一套外观一并应用到无 class 的 select 上，不必逐个去改 PHP。 */
select:not([class]) {
    /* 2026-09-18：去掉系统默认外观，改用统一的自定义箭头 ——
       原先右侧留了 24px 的 padding-right，箭头却仍是系统自带的，
       两边都不像样。箭头用内联 SVG（data URI），中灰色，
       深浅两套主题下都清晰。 */
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    /* 2026-09-19：纵向/左侧和并排的 #outer input:not([class])（见 :277）取同一档。
       原先纵向只有 --nx-space-2（4px），和输入框差 8px 高、还往下坠 4px，
       候选区筛选下拉那句「(显示全部)」就是这么显小的。右侧留 24px 给自定义箭头。 */
    padding: var(--nx-space-3) var(--nx-space-7) var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-base);
    color: var(--nx-text);
    background-color: var(--nx-surface);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1.5 2L6 6.2L10.5 2' fill='none' stroke='%2394a3b8' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--nx-space-4) center;
    background-size: 11px 7px;
    border: var(--nx-border-thin) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-inset);
    cursor: pointer;
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
select.med:hover {
    border-color: var(--nx-primary);
}
select.med:focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
/* 关键：option 在部分浏览器会继承系统配色，这里显式钉死浅底深字 */
select.med option,
#outer select option {
    padding: var(--nx-space-2) var(--nx-space-3);
    color: var(--nx-text);
    background-color: var(--nx-surface);
}
select.med option:checked,
#outer select option:checked {
    color: var(--nx-on-primary);
    background-color: var(--nx-primary);
}
select.med option:hover,
select.med option:focus {
    background-color: var(--nx-primary-soft);
    color: var(--nx-primary-strong);
}
/* 深色模式下 option 跟着反转 */
[data-nx-theme="dark"] select option,
.nx-dark select option {
    color: var(--nx-text);
    background-color: var(--nx-surface);
}
[data-nx-theme="dark"] select option:checked,
.nx-dark select option:checked {
    color: var(--nx-on-primary);
    background-color: var(--nx-primary);
}

/* ==========================================================================
   11. 界面外观面板（右下角悬浮按钮 + 弹出面板）
   --------------------------------------------------------------------------
   由 public/js/theme-switcher.js 动态创建，这里只负责外观。
   结构：标题行 → 4 个配色方案 → 分隔线 → 3 个明暗模式。
   全部走 var(--nx-*)，所以切配色/明暗时面板自身也跟着变，不会脱节。
   ========================================================================== */
.nx-theme-switch {
    position: fixed;
    right: var(--nx-space-7);
    bottom: var(--nx-space-7);
    z-index: 1300;                      /* 高于 --nx-z-toast(1200)，确保不被弹层盖住 */
    font-family: var(--nx-font-sans);
}

.nx-ts-trigger {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    padding: 0;
    font-size: var(--nx-font-lg);
    color: var(--nx-text-secondary);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-full);
    box-shadow: var(--nx-shadow-lg);
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-base) var(--nx-ease-spring),
                box-shadow var(--nx-dur-base) var(--nx-ease-out);
}
.nx-ts-trigger:hover {
    color: var(--nx-primary-strong);
    border-color: var(--nx-primary);
    transform: translateY(-2px);
    box-shadow: var(--nx-shadow-xl);
}
.nx-ts-trigger:active { transform: translateY(0); }

/* ---- 面板 ---- */
.nx-ts-panel {
    position: absolute;
    right: 0;
    bottom: calc(100% + var(--nx-space-3));
    width: 332px;
    max-width: calc(100vw - var(--nx-space-8));
    padding: var(--nx-space-4);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-card-border);
    border-radius: var(--nx-radius-xl);
    box-shadow: var(--nx-shadow-xl);
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px) scale(0.98);
    transform-origin: bottom right;
    transition: opacity var(--nx-dur-base) var(--nx-ease-out),
                transform var(--nx-dur-base) var(--nx-ease-out),
                visibility 0s linear var(--nx-dur-base);
}
.nx-ts-panel.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0) scale(1);
    transition-delay: 0s;
}

/* ---- 标题行 ---- */
.nx-ts-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--nx-space-4);
}
.nx-ts-heading {
    font-size: var(--nx-font-md);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text);
}
.nx-ts-reset {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    font-family: inherit;
    font-size: var(--nx-font-xs);
    color: var(--nx-text-secondary);
    background: transparent;
    border: 0;
    border-radius: var(--nx-radius-sm);
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
}
.nx-ts-reset:hover:not(:disabled) {
    color: var(--nx-primary-strong);
    background: var(--nx-surface-hover);
}
.nx-ts-reset:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---- 配色方案列表 ---- */
/* 这里【不要】用负外边距去抵消 .nx-ts-scheme 的横向内边距：卡片底色会跟着顶到面板边，
   选中项和未选中项的左缘也会互相错开。
   ⚠️ 2026-09-20 更正：下面这段 grid 的注释当初写错了因果。当时量到四个色块左缘
   错开 11px（457/468/479/468），父容器明明对齐 —— 真凶不是弹性布局本身，
   而是第 3 节那条全局 `button:not(...)` 用 (0,1,1) 的特异度把这里的 display:grid
   顶回了 inline-flex + justify-content:center，于是每行内容按自身宽度居中，
   文字长短不同 ⇒ 色块左缘跟着漂。换成 grid 并没有生效（被顶掉了），是后来把
   `nx-ts-` 加进那条规则的排除列表才真正对齐的。留着 grid：它是正确的写法。 */
.nx-ts-schemes {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* grid 固定第一列宽度，色块被强制落在同一条竖线上，文字列也从此对齐。 */
.nx-ts-scheme {
    display: grid;
    grid-template-columns: 42px 1fr;
    align-items: center;
    gap: var(--nx-space-3);
    width: 100%;
    padding: var(--nx-space-2) var(--nx-space-3);
    font-family: inherit;
    text-align: left;
    background: transparent;
    border: var(--nx-border-thin) solid transparent;
    border-radius: var(--nx-radius-lg);
    cursor: pointer;
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
.nx-ts-scheme:hover { background: var(--nx-surface-hover); }
/* 选中态：淡品牌色底 + 品牌色描边 */
.nx-ts-scheme.is-active {
    background: var(--nx-primary-soft);
    border-color: var(--nx-primary-border);
}

/* 色块：实心品牌色方块。
   颜色取 tokens.css 里的 --nx-swatch-<方案> 令牌，而不是写死在 JS/这里 ——
   同一方案在浅色与深色下拿到的品牌色不同（如深海蓝 #2563eb / #3b82f6），
   若写死一个值，面板里显示的颜色会和切过去之后的实际颜色对不上。
   末尾带 fallback，未定义该令牌的主题也能正常显示。 */
.nx-ts-swatch {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 42px;
    height: 42px;
    color: #fff;
    font-size: 15px;
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-sm);
}
.nx-ts-swatch[data-swatch="deep-blue"] { background: var(--nx-swatch-deep-blue, #2563eb); }
.nx-ts-swatch[data-swatch="jade"]      { background: var(--nx-swatch-jade,      #059669); }
.nx-ts-swatch[data-swatch="nebula"]    { background: var(--nx-swatch-nebula,    #7c3aed); }
.nx-ts-swatch[data-swatch="amber"]     { background: var(--nx-swatch-amber,     #d97706); }
/* 勾选只在选中时出现，避免四个色块都顶着对勾显得吵 */
.nx-ts-swatch .fa {
    opacity: 0;
    transform: scale(0.6);
    transition: opacity var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-base) var(--nx-ease-spring);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
}
.nx-ts-scheme.is-active .nx-ts-swatch .fa {
    opacity: 1;
    transform: scale(1);
}

.nx-ts-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.nx-ts-name {
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text);
}
.nx-ts-scheme.is-active .nx-ts-name { color: var(--nx-primary-strong); }
.nx-ts-desc {
    font-size: var(--nx-font-xs);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text-secondary);
}

.nx-ts-divider {
    height: 1px;
    margin: var(--nx-space-4) 0;
    background: var(--nx-divider);
}

/* ---- 明暗模式 ---- */
.nx-ts-modes {
    display: flex;
    gap: var(--nx-space-2);
    /* 和上方配色项一样贴齐面板的内容盒（左右都不额外内缩）：标题、分隔线、配色卡、
       模式按钮组四者的边框共用一条左竖线，右缘同理。配色卡里的色块比这条线再进
       8px，那是卡片自己的内边距，不是错位。
       （这里原先写的是 padding: 0 var(--nx-space-3)，意图是让模式按钮去对齐【色块】，
         但那条竖线本身是当时被全局按钮规则挤歪的假象，见第 3 节那条注释。） */
    padding: 0;
}
.nx-ts-mode {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 6px;
    padding: var(--nx-space-3) var(--nx-space-2);
    font-family: inherit;
    font-size: var(--nx-font-xs);
    color: var(--nx-text-secondary);
    background: var(--nx-surface-alt);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
.nx-ts-mode i { font-size: var(--nx-font-md); }
.nx-ts-mode:hover {
    color: var(--nx-primary-strong);
    border-color: var(--nx-primary-border);
    background: var(--nx-primary-soft);
}
/* 选中态：品牌色实底 + 反色文字（Cyber 深色下 --nx-on-primary 是深字，
   配亮蓝按钮对比度更高，比写死白字更稳） */
.nx-ts-mode.is-active {
    color: var(--nx-on-primary);
    background: var(--nx-primary);
    border-color: var(--nx-primary);
    font-weight: var(--nx-weight-medium);
}
/* ==========================================================================
   11b. 种子标签色重映射（内容语义色，与主题无关，故放共享层）
   --------------------------------------------------------------------------
   问题：种子标签由 PHP 直接输出内联 style，底色全是上古高饱和色号 ——
     #0000ff 纯蓝(官方,51) / #006400 深绿(中字,49) / #6a3906 深棕(国语,41) /
     #38b03f 草绿(HDR,35) / #336699 钢蓝(英字,25) / #00ffff 青(高帧,4) …
   一律「深底 + 白字」硬编码，不随主题变化。在任何浅色主题里都是一堆刺眼杂色块，
   换再好看的主题色也救不回来 —— 这才是页面「不好看」的主因。

   解法：属性选择器按原色号精确命中，重映射为「浅底 + 深字」马卡龙标签。
   不改任何 PHP，L1 层即生效；配色取 Tailwind 100/800 档，对比度均已达标。

   必须 !important —— 对手是内联 style（特异性最高）。
   只覆盖 color / background-color，padding / border-radius 等保留原内联值。

   ⚠️ 2026-09-22：选择器一律加 background / background-color 前缀，不再裸匹配色号。
   标签的真实 markup 是 <span style="background-color:#FF0000;color:#ffffff;…">
   （functions.php:6250 / TagRepository.php:78），而新闻正文的
   [color=#FF0000] 渲染成 <span style="color: #FF0000;"> —— 两者都能命中
   旧的 span[style*="#ff0000"]，于是整句公告被刷成一颗粉底标签，
   且拿到的是这里写死的 #be123c、不吃 --nx-danger-text，深色主题下不翻转。
   加前缀后：正文交下面 §11c 的 ^= 前缀规则管，标签仍由本节管。
   ========================================================================== */

span[style*="background:#0000ff" i],
span[style*="background-color:#0000ff" i] {
    background-color: #dbeafe !important; color: #1e40af !important;   /* 官方：纯蓝→柔蓝 */
}
span[style*="background:#006400" i],
span[style*="background-color:#006400" i] {
    background-color: #d1fae5 !important; color: #065f46 !important;   /* 中字：深绿→薄荷 */
}
span[style*="background:#6a3906" i],
span[style*="background-color:#6a3906" i] {
    background-color: #fed7aa !important; color: #9a3412 !important;   /* 国语：深棕→奶油橙 */
}
span[style*="background:#38b03f" i],
span[style*="background-color:#38b03f" i] {
    background-color: #bbf7d0 !important; color: #166534 !important;   /* HDR：草绿→浅绿 */
}
span[style*="background:#336699" i],
span[style*="background-color:#336699" i] {
    background-color: #e0e7ff !important; color: #3730a3 !important;   /* 英字/杜比：钢蓝→淡靛 */
}
span[style*="background:#f3e8ff" i],
span[style*="background-color:#f3e8ff" i] {
    background-color: #f3e8ff !important; color: #6b21a8 !important;   /* 分集：保留底色，压深文字 */
}
span[style*="background:#00acc1" i],
span[style*="background-color:#00acc1" i] {
    background-color: #cffafe !important; color: #155e75 !important;   /* 完结：青→冰蓝 */
}
span[style*="background:#ed8936" i],
span[style*="background-color:#ed8936" i] {
    background-color: #ffedd5 !important; color: #c2410c !important;   /* 高码：橙→蜜桃 */
}
span[style*="background:#00ffff" i],
span[style*="background-color:#00ffff" i] {
    background-color: #a5f3fc !important; color: #0e7490 !important;   /* 高帧：亮青→天青 */
}
span[style*="background:#46d5ff" i],
span[style*="background-color:#46d5ff" i] {
    background-color: #bae6fd !important; color: #075985 !important;   /* DIY：亮蓝→天空 */
}
span[style*="background:#4299e1" i],
span[style*="background-color:#4299e1" i] {
    background-color: #bfdbfe !important; color: #1e40af !important;   /* 臻彩MAX：蓝→粉蓝 */
}
span[style*="background:#e65100" i],
span[style*="background-color:#e65100" i] {
    background-color: #ffe4e6 !important; color: #be123c !important;   /* 高分：深橙→浅珊瑚 */
}
span[style*="background:#ff0000" i],
span[style*="background-color:#ff0000" i] {
    background-color: #fecdd3 !important; color: #be123c !important;   /* 禁转：纯红→浅粉红 */
}
span[style*="background:#8f77b5" i],
span[style*="background-color:#8f77b5" i] {
    background-color: #ede9fe !important; color: #6b21a8 !important;   /* 首发：紫→薰衣草 */
}
span[style*="background:#9c27b0" i],
span[style*="background-color:#9c27b0" i] {
    background-color: #fae8ff !important; color: #a21caf !important;   /* 去广告：品红→浅品红 */
}
span[style*="background:#1a73e8" i],
span[style*="background-color:#1a73e8" i] {
    background-color: #dbeafe !important; color: #1e40af !important;   /* 特效：蓝→柔蓝 */
}

/* 置顶行：100 处浅青蓝 #89c9e6 → 主题下沉色 */
tr[style*="#89c9e6" i], tr[style*="#89C9E6" i],
td[style*="#89c9e6" i], td[style*="#89C9E6" i] {
    background-color: var(--nx-surface-sunken) !important;
}

/* 通知条：<td style="background: blue"> */
td[style*="background: blue" i], td[style*="background:blue" i],
td[style*="background-color: blue" i], td[style*="background-color:blue" i] {
    background-color: var(--nx-primary-soft) !important;
    color: var(--nx-text) !important;
}

/* <font color> 上古色号 → 语义色 */
font[color="#0000ff" i], font[color="#0000FF" i], font[color="blue" i] {
    color: var(--nx-info-text) !important;
}
font[color="green" i], font[color="#00cc66" i], font[color="#00CC66" i],
font[color="#008000" i] {
    color: var(--nx-success-text) !important;
}
font[color="red" i], font[color="#ff0000" i], font[color="#FF0000" i] {
    color: var(--nx-danger-text) !important;
}
font[color="indigo" i] {
    color: var(--nx-primary-strong) !important;
}

/* ---- 2026-09-22 补：把「上古色号」名单从 4 个扩到全站实际在用的全套 ----------
   为什么要一起管 <font color> 和 <span style="color:…">：
   新闻/公告是后台用 BBCode 手写的，[color=#D82E2F] 经 format_comment()
   （include/functions.php:352）渲染成 <span style="color: #D82E2F;">，
   而 [size=5] 渲染成 <font size="5"> —— 同一段内容两种标记，只堵一边等于没堵。
   span 侧沿用 §11b 的 ^= 前缀匹配（避免误伤 background-color: …）。

   原则：**只换色档、不换色相**。作者写红/绿/琥珀/紫是设计意图（公告分级、
   喜庆色），保留其色相家族，把它落到会随明暗翻转的语义令牌上 ——
   原来 #EEEEEE 这类浅灰在深色下正常、浅色下等于隐形，#3366FF 在深色底上只有
   2.2:1，都是「色相对、明度档错」。

   ⚠️ 名单里没有的：color="white" —— 那几颗是**故意**写在深色底上的
   （functions.php:93 SQL 报错块、:3795 站点关闭提示、:6912 广告条、settings.php:28）。
   它们不走这里的色档，改由 §6 的 .msgalert 组件承担：msgalert()/sqlerr()/离线提示/
   settings 顶部公告已改成「软底 + -text 字」，底色随明暗翻转，白字标记一并删掉。
   （messages.php:282、staffbox.php:124 两处原本是白字压在**没有底色**的单元格上，
    浅色主题下等于隐形，属于纯 bug，直接去掉了 <font> 包裹。）
   ------------------------------------------------------------------------- */
/* 红族：#D82E2F / #E53935 / #FF3300 / #D32F2F / #FF0000 —— 公告主标题
   （#FF0000 原先是被 §11b 标签节的裸子串匹配「顺带」染上的，收紧后必须在这里列出，
    否则正文退回裸红 rgb(255,0,0)，深底上只有 3.8:1） */
font[color="darkred" i],
span[style^="color: #ff0000;" i], span[style^="color:#ff0000;" i],
span[style^="color: #d82e2f;" i], span[style^="color:#d82e2f;" i],
span[style^="color: #e53935;" i], span[style^="color:#e53935;" i],
span[style^="color: #ff3300;" i], span[style^="color:#ff3300;" i],
span[style^="color: #d32f2f;" i], span[style^="color:#d32f2f;" i] {
    color: var(--nx-danger-text) !important;
}
/* 绿族：#2E8B57 海绿 / #1F7309 站内链接绿 / #006400 深绿 / #38B03F 草绿 */
span[style^="color: #2e8b57;" i], span[style^="color:#2e8b57;" i],
span[style^="color: #1f7309;" i], span[style^="color:#1f7309;" i],
span[style^="color: #006400;" i], span[style^="color:#006400;" i],
span[style^="color: #38b03f;" i], span[style^="color:#38b03f;" i] {
    color: var(--nx-success-text) !important;
}
/* 蓝族：#1E90FF 亮天蓝 / #3366FF 公告蓝 / #4299E1 / #00FFFF 亮青 / #46D5FF */
span[style^="color: #1e90ff;" i], span[style^="color:#1e90ff;" i],
span[style^="color: #3366ff;" i], span[style^="color:#3366ff;" i],
span[style^="color: #4299e1;" i], span[style^="color:#4299e1;" i],
span[style^="color: #00ffff;" i], span[style^="color:#00ffff;" i],
span[style^="color: #46d5ff;" i], span[style^="color:#46d5ff;" i] {
    color: var(--nx-info-text) !important;
}
/* 深蓝族：#0066CC / #0288D1 / #1A73E8 / #336699 钢蓝 —— 归主色而非信息色，和链接同档 */
span[style^="color: #0066cc;" i], span[style^="color:#0066cc;" i],
span[style^="color: #0288d1;" i], span[style^="color:#0288d1;" i],
span[style^="color: #1a73e8;" i], span[style^="color:#1a73e8;" i],
span[style^="color: #336699;" i], span[style^="color:#336699;" i] {
    color: var(--nx-primary-strong) !important;
}
/* 琥珀族：#E69A49 分隔线 / #B35C00 正文 / #6A3906 深棕 / #ED8936 橙 / #E65100 深橙 */
span[style^="color: #e69a49;" i], span[style^="color:#e69a49;" i],
span[style^="color: #b35c00;" i], span[style^="color:#b35c00;" i],
span[style^="color: #6a3906;" i], span[style^="color:#6a3906;" i],
span[style^="color: #ed8936;" i], span[style^="color:#ed8936;" i],
span[style^="color: #e65100;" i], span[style^="color:#e65100;" i] {
    color: var(--nx-warning-text) !important;
}
/* 橙红族：#FF4500 橙红 / #FF6F00 琥珀橙 —— 强调级，用色相档不用 -text
   （-text 是给文字对比度调的，这几档本身偏暗，实心强调会发脏；见 9-22 图标那批的结论） */
span[style^="color: #ff4500;" i], span[style^="color:#ff4500;" i],
span[style^="color: #ff6f00;" i], span[style^="color:#ff6f00;" i] {
    color: var(--nx-warning) !important;
}
/* 紫族：#673AB7 Material 深紫 / #9C27B0 品红（#9932CC 中紫罗兰 §11b 已经管了） */
span[style^="color: #673ab7;" i], span[style^="color:#673ab7;" i],
span[style^="color: #9c27b0;" i], span[style^="color:#9c27b0;" i] {
    color: var(--nx-primary-strong) !important;
}
/* 灰族：#EEEEEE 浅灰 / #9E9E9E 中灰 / #424242 炭灰 —— 三个都是「次要说明」，
   浅灰在浅色主题下几乎隐形，是这批里唯一的硬 bug，必须落到随主题翻转的文字档。 */
span[style^="color: #eeeeee;" i], span[style^="color:#eeeeee;" i],
span[style^="color: #9e9e9e;" i], span[style^="color:#9e9e9e;" i],
span[style^="color: #424242;" i], span[style^="color:#424242;" i],
span[style^="color: #f3e8ff;" i], span[style^="color:#f3e8ff;" i] {
    color: var(--nx-text-secondary) !important;
}

/* --- 2026-09-17 补：计算样式探针发现的两个漏网 --------------------------------
   ① §11b 原先只匹配 hex 子串，吃不到「关键字写法」color: blue
      （details 简介「TJUPT官组作品…」、tags 示例「这是蓝色文字」，深底上 1.79:1）；
   ② #9932cc（后台富文本写的紫）根本不在名单里
      （index 福利标题，深底上 2.7:1）。
   这两处都是【正文/标题文字】而非标签 → 只改文字色，不做浅底胶囊
   （与上面 font[color="blue"] 的处理一致，避免把一整句话变成标签块）。
   用 ^=（前缀匹配）而不是 *=：避免误伤 background-color: blue; 这类声明。 */
span[style^="color: blue;" i], span[style^="color:blue;" i] {
    color: var(--nx-info-text) !important;
}
span[style^="color: red;" i], span[style^="color:red;" i] {
    color: var(--nx-danger-text) !important;
}
span[style^="color: green;" i], span[style^="color:green;" i] {
    color: var(--nx-success-text) !important;
}
span[style^="color: #9932cc;" i], span[style^="color:#9932cc;" i] {
    color: var(--nx-primary-strong) !important;
}

/* --- 2026-09-24 补：font[color] 兜底的最后一批漏网色值 ------------------------
   全站 <font color=…> 实测 169 处，上面 §11c 已覆盖 red/green/blue/darkred/indigo
   约 150 处，本节收掉剩下这些：
     gray ×6   forums.php:753/756/1302/1307、functions.php:4152/4154（发帖人/时间/浏览量）
     orange ×1 offers.php:793（offer 待审标记）
     purple ×1 log.php:143 动态拼出来的 <font color='purple'>（上传/删除/编辑/请求日志分色）
     #1f7309 / #ca0226 ×3 invite.php:208/210/300 —— 属性写法，§11c 的绿族只登记了
               span[style] 侧，<font color=#1f7309> 这种带 # 的**无引号属性**同样要单独列。

   ⚠️ 仍未覆盖（P3 明确不做）：get_ratio_color()/get_slr_color() 的 #ff0000→#660000
      十档分享率色阶。注意 <font color="#ff0000"> 恰好命中上面的 red 规则，
      所以最低那一档已被换成 --nx-danger-text，其余九档仍是原色号 —— 已知不对称，
      浅色底上 #660000~#ee0000 都可读，暂不处理。
   ⚠️ 论坛主题高亮 get_hl_color()（functions.php:5971）的 31 个具名色（Black/Sienna/
      Navy/DarkOrange/Yellow/Lime/Cyan…）走的是同一条 <font color> 通道。其中
      Gray/Green/Blue/Red/Indigo/DarkRed/Orange/Purple 这 8 档已被本节和 §11c 接住，
      其余（Navy、Sienna、Yellow、Lime、Cyan…）仍是原色 —— 属于 P3「主题色板」，
      全部归并会让作者手选的高亮色塌成 5 个色相家族，需先确认再动。 */
font[color="gray" i] {
    color: var(--nx-text-secondary) !important;
}
font[color="#1f7309" i] {
    color: var(--nx-success-text) !important;
}
font[color="orange" i] {
    color: var(--nx-warning-text) !important;
}
font[color="purple" i] {
    color: var(--nx-primary-strong) !important;
}
font[color="#ca0226" i] {
    color: var(--nx-danger-text) !important;
}

/* --- 2026-09-24 补：老式表格的 bgcolor 属性 ----------------------------------
   mysql_stats.php 整页用 bgcolor 手写配色：lightgrey 是分组表头、#EFF3FF 是斑马行，
   都是写死的浅底，深色主题下变成两块亮斑。管理页专用，零 PHP 改动即可归位。 */
th[bgcolor="lightgrey" i], th[bgcolor="#EFF3FF" i],
td[bgcolor="lightgrey" i], td[bgcolor="#EFF3FF" i] {
    background-color: var(--nx-surface-sunken) !important;
    color: var(--nx-text) !important;
}

/* --- 2026-09-24 补：「这是你自己」高亮格 --------------------------------------
   usersearch.php:44 / viewpeerlist.php:116 用 #BBAF9B、viewsnatches.php:47 用 #00A527、
   ipcheck.php:69 用 #ECE9D8、usersearch.php:17 用 #F5F4EA —— 全是「把当前用户那一行
   标出来」的写死浅底，深色主题下是一整块亮棕/亮绿横条。
   语义就是「选中行」，直接落到 --nx-surface-active（站点已有该令牌，明暗都调过）。 */
td[bgcolor="#BBAF9B" i], td[bgcolor="#00A527" i], td[bgcolor="#ECE9D8" i],
td[bgcolor="#F5F4EA" i], tr[bgcolor="#BBAF9B" i], tr[bgcolor="#00A527" i],
tr[bgcolor="#ECE9D8" i], tr[bgcolor="#F5F4EA" i] {
    background-color: var(--nx-surface-active) !important;
}

/* --- 2026-09-24 补：下拉项里写死的文字色 --------------------------------------
   faqactions.php 的状态下拉（Hidden/Normal/Updated/New 共 12 处）把颜色写在
   <option style="color: #000000"> 上。#000000 那档在深色主题的下拉面板里等于隐形
   —— 面板底是 --nx-surface（深色），黑字压上去完全读不出。
   ⚠️ 不含 forums.php:842 的高亮取色器：那里的 option 背景色就是「选项本身代表的颜色」，
      是色板而非装饰，必须保持写死，不能令牌化。 */
option[style*="color: #000000" i], option[style*="color:#000000" i] {
    color: var(--nx-text) !important;
}
option[style*="color: #ff0000" i], option[style*="color:#ff0000" i] {
    color: var(--nx-danger-text) !important;
}
option[style*="color: #0000ff" i], option[style*="color:#0000ff" i] {
    color: var(--nx-info-text) !important;
}
option[style*="color: #008000" i], option[style*="color:#008000" i] {
    color: var(--nx-success-text) !important;
}

/* --- 2026-09-17 补：老式表单表的宽度治理 --------------------------------------
   upload / edit 的表单表（`<table border="1" width="97%">`，含 td.colhead 标签列）
   内部有 `<textarea cols="100">` 等元素，贡献了巨大的 min-content（实测表宽 1303px），
   反把容器顶破（内容区 max-width=1200）→ 用户看到「上边的框比下边的窄」。
   用 :has() 精确锁定「含 colhead 的表」，不影响真正的数据表（topten / stats / torrents 等）；
   table-layout:fixed 让表遵守它已声明的 width，单元格不再被内容反向撑开。 */
#outer table:has(> colgroup) { table-layout: fixed; }

/* 标签列宽度由「表格自身的 <colgroup><col style="width:180px">」声明 ——
   fixed 布局【只看首行】定列宽，而本表首行是 colspan=2 单元格；
   实测：无论给首行单元格多大宽度，两列都会被均分成 50/50（CSS 无解）。
   <col> 的宽度优先于首行单元格，是唯一可靠方式。
   落点：public/upload.php:43 、 public/edit.php:60 各自的 <table> 之后。 */

/* BBCode 编辑器是一张【嵌套宽表】（实测 1197px：11 个工具栏单元格 + 30 个表情单元格 +
   textarea cols="100" + 附件 iframe），塞在窄单元格里必然溢出 → 「简介」那块被顶破。

   ⚠ 已尝试并【回滚】的三种 CSS 方案（都不行，勿再重试）：
     1. max-width:100%                  → 对 display:table 无效（实测仍 1197px）
     2. width:100% + table-layout:fixed → 盒子收窄了但内部单元格被压成 ~17px，
                                          内容照样溢出，**肉眼无改善**
     3. display:block + overflow-x:auto → 让内部匿名表格盒重算，
                                          导致【附件 iframe 那一行整行塌掉、iframe 消失】← 用户实测
   ⇒ 结论：**这个问题 CSS 无解**，必须改标记：把编辑器那张嵌套表用一个
      `<div style="overflow-x:auto">` 包起来（标记级改动，见 upload.php / edit.php）。
      在标记加包裹层之前，这里不做任何处理，保持原状。 */

/* 已落地：BBCode 编辑器容器表由 include/functions.php 用 <div class="nx-editor-scroll"> 包住。
   透明滚动容器 —— 表格（含内部附件 iframe）照常渲染，超宽部分变成横向滚动。 */
.nx-editor-scroll {
    overflow-x: auto;
    max-width: 100%;
}

/* 2026-09-17 · 表单标签列统一右对齐。
   实测：除「简介*」外，其余标签格都由 tr() 生成并带 inline align="right"；
   「简介」那行是手工写的、没有 align → 计算值 textAlign=start，是唯一左对齐的，看着违和。
   （给所有 rowhead 补 text-align:right，对齐已有的 inline 值，不改动任何一行标记。） */
#outer table:has(> colgroup) td.rowhead { text-align: right; }

/* 2026-09-17 · 搜索面板标签折行问题：暂不动（两次尝试都失败，详见下）
   ① white-space:nowrap → 抬高各标签列 min-content，整页横向溢出（803>708）
   ② td:first-child{width:96px} → 命中的不是标签格，标签格反而缩到 45px、行高 90→130 更糟
   现状：标签格约 72px（≈表格 10%），「搜索关键字:」折成两行。
   下次要改先看 public/torrents.php:1016 起的 <table class="searchbox"> 真实行/列结构
   （注意：面板内容在 tbody#ksearchboxmain 里，默认 display:none，是可折叠的）。 */

/* 2026-09-17 · 附件上传 iframe 高度。
   原 height="24" 是按「未接设计系统的紧凑表单」量的；attachment.php 接入设计系统后
   内容多了内边距、实际更高，24px 只够露出空白 → 用户反馈「那一横条里看不到内容」。 */
#outer iframe[src*="attachment"] { height: 60px; }

/* 2026-09-18 · 搜索箱两处修复（用与编辑器工具栏同一套手法）
   ① 展开搜索箱后页面变宽：箱内的选项网格是「一行 10~14 个 <td class="bottom">」，
      其 min-content = 所有列之和(~1030px) → 把整个内容区撑宽。
      → 把这类行改成【可换行 flex 行】：单元格宽度不变，不够时自动换到下一行，
      min-content 降到「最宽的单格」，页面宽度不再被撑。
   ② 分类等选择格错位：原 vertical-align:middle + 各格内容行数不同 → 复选框上下错开(实测差 22px)。
      → 行改 flex 后按 flex-start 对齐，并让复选框本身顶对齐，所有格的复选框落在同一水平线。 */
#outer tr:has(> td.bottom) { display: flex; flex-wrap: wrap; align-items: flex-start; }
#outer tr:has(> td.bottom) > td { display: block; vertical-align: top; }
#outer table.searchbox td.bottom > input[type="checkbox"] { vertical-align: top; margin-top: 2px; }

/* --------------------------------------------------------------------------
   2026-09-18 · 搜索箱选项栅格：分类做小卡片、其余等宽对齐
   --------------------------------------------------------------------------
   原状：分类格是「复选框 + 45×46 图标」横向挤在 td 里，复选框顶对齐而图标很高
   → 错位明显；且每格宽 = 内容宽，换行后每行格数不定，「全选」按钮位置随换行浮动。
   做法：分类格 → 固定尺寸小卡片，复选框绝对定位到左上角；
         其余格 → 统一最小宽度并垂直居中。
   ========================================================================== */

/* 分类格：图标卡片
   ⚠️ 分类图标是 sprites：img.c_xxx 靠 45×46 的框 + background-position 取一格。
      框尺寸一旦被改（例如 base.css 的 img{max-width:100%} 在 flex 收缩时压扁它），
      background-position 就对不上，只会露出雪碧图的一角 —— 这正是种子列表
      「图标显示不全」踩过的坑。所以这里让格子不参与收缩，并把 img 尺寸钉死。 */
#outer tr:has(> td.bottom) > td.bottom:has(> a > img) {
    position: relative;
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 60px;
    box-sizing: border-box;
    padding: 0 !important;
    margin: 3px;
    border: var(--nx-border-thin) solid transparent;
    border-radius: var(--nx-radius-md);
    background: var(--nx-surface-alt);
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
#outer tr:has(> td.bottom) > td.bottom:has(> a > img):hover {
    background: var(--nx-surface-hover);
    box-shadow: var(--nx-shadow-sm);
}
/* 分类图标：钉死 sprites 格尺寸，禁止被压缩 */
#outer table.searchbox td.bottom > a > img[class^="c_"] {
    max-width: none;
    width: 45px;
    height: 46px;
    flex-shrink: 0;
}
/* 已勾选的分类：整张卡片主色高亮，与下面选项胶囊的选中态用同一套语言 */
#outer tr:has(> td.bottom) > td.bottom:has(> a > img):has(> input[type="checkbox"]:checked) {
    background: var(--nx-primary-soft);
    border-color: var(--nx-primary-border);
    box-shadow: var(--nx-shadow-sm);
}
/* 复选框浮到图标左上角，不再与图标抢横向空间 */
#outer tr:has(> td.bottom) > td.bottom:has(> a > img) > input[type="checkbox"] {
    position: absolute;
    left: 5px;
    top: 5px;
    margin: 0;
    z-index: 1;
}

/* 其余选项格（媒介 / 编码 / 分辨率 / 音频编码 / 制作组 …）
   原状：只有「裸复选框 + 文字」，既没有可点击区域的视觉暗示，也看不出哪些已勾选。
   改为胶囊标签：等宽、整格可点、悬浮有反馈、勾选后整颗高亮。

   ⚠️ 复选框不是 <td> 的直接子元素！build_search_box_category_table() 输出的结构是
          <td class="bottom"><label><input type="checkbox">…<a>选项名</a></label></td>
      实测 directChildren=LABEL。所以必须用后代匹配 :has(input[type="checkbox"])；
      写成 :has(> input[type="checkbox"]) 会因为多一层 <label> 而永远不匹配（踩过）。
   ⚠️ :not(:has(img)) 用来摘掉分类卡片：分类卡片同样有复选框，但结构是
          <td class="bottom"><input type="checkbox"><a><img class="c_xxx"></a></td>
      复选框是直接子，靠 :has(img) 排除。
   ⚠️ 右侧「显示断种/活种?」「显示促销种子?」那一列的 <td class="bottom">
      （内容是 <span class="medium"> / <select>，不含复选框）也在这张表里，
      靠 :has(input checkbox) 一并排除。 */
#outer tr:has(> td.bottom) > td.bottom:has(input[type="checkbox"]):not(:has(img)) {
    display: inline-flex;
    align-items: center;
    min-width: 116px;
    box-sizing: border-box;
    margin: 2px;
    padding: 4px var(--nx-space-3) !important;
    white-space: nowrap;
    font-size: var(--nx-font-sm);
    color: var(--nx-text-secondary);
    background: var(--nx-surface-alt);
    /* 浅色下 --nx-surface-alt (#f8fafc) 与页面白底几乎同色，边框若为 transparent
       整颗胶囊就糊进背景里 → 给实边框。宽度恒为 1px，勾选态只换颜色，不产生布局位移。 */
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: 999px;
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
#outer tr:has(> td.bottom) > td.bottom:has(input[type="checkbox"]):not(:has(img)):hover {
    color: var(--nx-text);
    background: var(--nx-surface-hover);
}
/* 勾选态：整颗胶囊变主色浅底 + 主色描边 + 主色文字 */
#outer tr:has(> td.bottom) > td.bottom:has(input[type="checkbox"]:checked):not(:has(img)) {
    color: var(--nx-primary-strong);
    font-weight: var(--nx-weight-medium);
    background: var(--nx-primary-soft);
    border-color: var(--nx-primary-border);
}
/* 复选框与选项名之间的间距：胶囊里唯一的直接子元素是 <label>，gap 得落在它身上
   （写在 td 上不生效 —— td 只有一个 flex item，gap 没有可作用的间隙） */
#outer tr:has(> td.bottom) > td.bottom > label {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-2);
    margin: 0;
    cursor: pointer;
}
/* 胶囊内的选项名是 <a>，默认带 UA 链接色 → 改为继承胶囊配色，勾选态才能同步变色
   （注意用后代选择器：<a> 也被包在 <label> 里） */
#outer tr:has(> td.bottom) > td.bottom a {
    color: inherit;
    text-decoration: none;
}
/* 「全选」按钮格：与最后一颗胶囊留出间距 */
#outer tr:has(> td.bottom) > td.bottom:has(> input.btn) {
    margin-left: var(--nx-space-2);
}

/* 「全选」按钮：胶囊化，与选项格同高
   原先 2px/12px 内边距 + 12px 字号做出来只有 ~22px 高，用户反馈「按钮太小了」。
   改成正文级字号（13px）、与选项胶囊等高的 29px、主色系描边，让它像个真正的操作按钮。 */
#outer tr:has(> td.bottom) > td.bottom > input.btn {
    min-width: 0;
    min-height: 29px;
    padding: 5px var(--nx-space-4) !important;
    font-size: var(--nx-font-base);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text);
    background: var(--nx-surface) !important;
    border: var(--nx-border-thin) solid var(--nx-border-strong) !important;
    border-radius: 999px;
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
#outer tr:has(> td.bottom) > td.bottom > input.btn:hover {
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft) !important;
    border-color: var(--nx-primary-border, var(--nx-border-strong)) !important;
}

/* 主标签（分类 / 媒介 / 编码 / 分辨率 / 音频编码 / 制作组 …）
   build_search_box_category_table() 把它们输出成「单独占一行的
   <td class="embedded">」，于是套上了通用的 td.embedded 样式
   （padding 20px + 卡片底 + 圆角）—— 在本表里又大又散，和下面的选项格不成层级。
   改成紧凑小节标题：透明底 + 左侧主色竖条 + 底部分隔线。

   ⚠️ 选择器必须限定 :only-child：本表其它行都是「一行多个 td」的选项行，
      只有小节标题行是「单格独占一行」，用这一点区分，不会误伤选项格。 */
#outer table.searchbox tr:has(> td.embedded:only-child) > td.embedded {
    position: relative;
    background: transparent;
    border-radius: 0;
    border-bottom: var(--nx-border-thin) solid var(--nx-border);
    padding: var(--nx-space-4) 0 var(--nx-space-2) var(--nx-space-3) !important;
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-primary-strong);
    letter-spacing: 0.03em;
}
/* 左侧主色竖条：高度跟随文字块，标题折行也不会脱节 */
#outer table.searchbox tr:has(> td.embedded:only-child) > td.embedded::before {
    content: "";
    position: absolute;
    left: 0;
    top: var(--nx-space-4);
    bottom: var(--nx-space-2);
    width: 3px;
    border-radius: 999px;
    background: var(--nx-primary);
}

/* 主标签图标：挂在 span.nx-sb-label 的 ::before 上
   （td 的 ::before 已被左侧竖条占用；标签格里的子节点只有文本节点，
     没有元素可挂伪元素，所以 build_search_box_category_table() 会输出这层 span）。

   ⚠️ 必须按 data-nx-tax 区分维度，不能靠匹配标签文字：getTaxonomyLabel() 允许后台
      用 extra.taxonomy_labels[].display_text 覆盖译文，同一维度在不同语言/配置下
      文字都不一样。
   ⚠️ 码点取自 public/css/font-awesome/5.15.4/css/all.min.css（用脚本正则提取），
      未凭记忆写 —— 例如 desktop 实际是 \f108 而非常被误记的 \f109。 */
#outer td.embedded[data-nx-tax] > .nx-sb-label::before {
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    display: inline-block;
    min-width: 1.15em;
    margin-right: var(--nx-space-2);
    color: var(--nx-primary);
    text-align: center;
}
#outer td.embedded[data-nx-tax="category"] > .nx-sb-label::before { content: "\f009"; } /* th-large 网格 */
#outer td.embedded[data-nx-tax="medium"] > .nx-sb-label::before { content: "\f008"; } /* film 胶片 */
#outer td.embedded[data-nx-tax="codec"] > .nx-sb-label::before { content: "\f121"; } /* code 代码 */
#outer td.embedded[data-nx-tax="standard"] > .nx-sb-label::before { content: "\f108"; } /* desktop 分辨率 */
#outer td.embedded[data-nx-tax="audiocodec"] > .nx-sb-label::before { content: "\f001"; } /* music 音频 */
#outer td.embedded[data-nx-tax="team"] > .nx-sb-label::before { content: "\f0c0"; } /* users 制作组 */
#outer td.embedded[data-nx-tax="source"] > .nx-sb-label::before { content: "\f1c0"; } /* database 来源 */
#outer td.embedded[data-nx-tax="processing"] > .nx-sb-label::before { content: "\f085"; } /* cogs 处理方式 */

/* 选项复选框：统一尺寸与配色（原先直接用浏览器默认外观，与设计系统不搭）
   用后代匹配：选项格的复选框包在 <label> 里，分类卡片的才是 <td> 直接子，两者都要覆盖。 */
#outer table.searchbox td.bottom input[type="checkbox"] {
    width: 14px;
    height: 14px;
    margin: 0;
    accent-color: var(--nx-primary);
    cursor: pointer;
    flex-shrink: 0;
}
/* 老页面里大量 width="97%" 的表与同级 100% 元素（如搜索箱）宽度不一致 → 统一到 100% */
#outer table[width="97%"] { width: 100% !important; }

/* 2026-09-17 · BBCode 编辑器工具栏：11 个单元格 → 可换行 flex 行。
   原先一行排完整合 ~1174px，是编辑器 min-width 达 1197px 的主因（次因 textarea cols=100）；
   换成换行布局后编辑器不再需要横向滚动。
   tr{display:flex} 让 <td> 变成 flex item 并可换行。 */
table.nx-toolbar > tbody > tr {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nx-space-1, 2px);
    align-items: center;
}
table.nx-toolbar > tbody > tr > td { display: block; }
/* 3 个下拉（颜色 / 字体 / 字号）原各占 ~155~168px，收窄以免吃掉大半个工具栏 */
table.nx-toolbar select.med.codebuttons { width: 110px; max-width: 110px; }

/* ==========================================================================
   2026-09-18 · 热门「海报墙」+ 自动流动（无缝循环 marquee）
   --------------------------------------------------------------------------
   标记由 include/functions.php 生成：
     <div class="nx-poster-wall"><div class="nx-poster-track">…海报×2…</div></div>
   内容输出两遍 + track 平移 -50% ⇒ 无缝循环（到一半时第二份正好接上第一份）。
   悬停暂停方便点选；prefers-reduced-motion 下不动。
   ========================================================================== */
/* ⚠ track 必须【绝对定位】：普通流里的宽内容会把父表格的 min-content 撑大
   （实测墙自己被撑到 2172px → 页面横向溢出）。脱离文档流后，墙的宽度回归父容器、
   overflow:hidden 才真正起裁切作用；代价是墙要自己给一个高度。 */
.nx-poster-wall {
    position: relative;
    overflow: hidden;
    height: 156px;                 /* 海报 140 + hover 抬升与阴影留白 */
    /* 两端柔和淡出（深色主题下尤其自然） */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
}
.nx-poster-track {
    position: absolute;
    left: 0;
    top: 50%;
    display: flex;
    gap: var(--nx-space-3, 8px);
    width: max-content;
    animation: nx-poster-flow 60s linear infinite;
    will-change: transform;
}
.nx-poster-wall:hover .nx-poster-track { animation-play-state: paused; }
/* 关键帧里必须带上 translateY(-50%)，否则动画的 transform 会覆盖掉垂直居中 */
@keyframes nx-poster-flow {
    from { transform: translateY(-50%) translateX(0); }
    to   { transform: translateY(-50%) translateX(-50%); }
}
.nx-poster-track > a { display: block; flex: 0 0 auto; margin: 0 !important; }
.nx-poster-track img {
    display: block;
    width: 101px;
    height: 140px;
    object-fit: cover;
    border-radius: var(--nx-radius-md, 10px);
    box-shadow: var(--nx-shadow-sm);
    transition: transform var(--nx-dur-base, 0.18s) var(--nx-ease-spring, ease),
                box-shadow var(--nx-dur-base, 0.18s) var(--nx-ease-out, ease);
}
.nx-poster-track > a:hover img { transform: translateY(-4px) scale(1.03); box-shadow: var(--nx-shadow-lg); }
@media (prefers-reduced-motion: reduce) {
    .nx-poster-track { animation: none; }
    .nx-poster-track > a:hover img { transform: none; }
}

/* ==========================================================================
   2026-09-17 · 文件选择控件美化（用户反馈「上传这个按钮能美化下吗」）
   --------------------------------------------------------------------------
   原生 input[type=file] 完全不受主题控制：系统灰底、系统字号，在深色主题上尤其突兀。
   用 ::file-selector-button 把「选择文件」按钮主题化（Chrome/Edge 89+ 支持）。
   全局生效（不加 #outer 前缀）—— attachment.php 附件 iframe 也会加载本文件，一并受益。
   ========================================================================== */
input[type="file"] {
    color: var(--nx-text-secondary);
    font-family: var(--nx-font-sans, inherit);
    font-size: var(--nx-font-base, 13px);
    max-width: 100%;
}
input[type="file"]::file-selector-button {
    margin-right: var(--nx-space-3, 8px);
    padding: var(--nx-space-2, 4px) var(--nx-space-4, 12px);
    font: inherit;
    font-size: var(--nx-font-sm, 12px);
    color: var(--nx-text);
    background: var(--nx-btn-bg, var(--nx-surface-alt));
    border: var(--nx-border-thin, 1px) solid var(--nx-border-strong);
    border-radius: var(--nx-radius-sm, 6px);
    cursor: pointer;
    transition: background-color var(--nx-dur-fast, 0.12s) var(--nx-ease-out, ease),
                border-color var(--nx-dur-fast, 0.12s) var(--nx-ease-out, ease),
                color var(--nx-dur-fast, 0.12s) var(--nx-ease-out, ease);
}
input[type="file"]::file-selector-button:hover {
    background: var(--nx-surface-hover, var(--nx-surface-alt));
    border-color: var(--nx-primary);
    color: var(--nx-primary-strong);
}
input[type="file"]:disabled::file-selector-button { opacity: 0.55; cursor: not-allowed; }

   12. 响应式
   ========================================================================== */
@media (max-width: 900px) {
    .form-control-row { flex-direction: column; align-items: stretch; gap: var(--nx-space-2); }
    .form-control-row .label { width: auto; }
}

@media (max-width: 768px) {
    /* 小屏下表格允许横向滚动而非撑破布局 */
    table.nx-table,
    table.torrents { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
    table.nx-table > thead, table.torrents > thead { display: table-header-group; }
}

/* ══════════════════════════════════════════════════════════════════════════
   未登录「内容页」的裸表格表单 —— recover / confirm_resend / signup(关闭提示)
   ══════════════════════════════════════════════════════════════════════════
   2026-09-18 新增。用户反馈「找回密码这两处颜色不对」。

   根因：这三个页面往 `#nav_block` 里直接塞 `<h1> + <p> + <form> + <table border="1">`，
   **完全没有被设计系统接管** —— 表格是上古写法（border 属性画白框、
   直角、rowhead 列自带底色），输入框没配背景（暗色下是刺眼的纯白，
   浅色下反而是深灰），表格宽度按内容收缩到 240px 左右、右侧空一大片。

   ⚠️ 为什么用 `#nav_block:has(> form > table[border])` 作作用域：
      判断依据是「nav_block 里直接装着带 border 属性的表格」——
      recover / confirm_resend / signup 都符合，而真正的导航页
      （含 ul.menu）没有这种结构，不会误伤。
      `> form > table` 的层级关系是实测出来的，不是猜的。
   ⚠️ 不写 `#outer`：这些页面**没有 #outer**（见下方登录页段落的说明）。

   设计目标：把它做成与 login 页同语言的「居中卡片 + 现代表单」。
   ══════════════════════════════════════════════════════════════════════ */

/* 页面标题与说明段落 —— 居中、收敛，与表格卡形成呼吸感 */
#nav_block:has(> form > table[border]) > h1 {
    margin: var(--nx-space-4) 0 var(--nx-space-5);
    text-align: center;
    font-size: var(--nx-font-2xl);
    font-weight: var(--nx-weight-bold);
    color: var(--nx-text);
}
#nav_block:has(> form > table[border]) > p {
    margin: var(--nx-space-3) 0;
    text-align: center;
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
    line-height: 1.9;
}
/* ⚠️ 最后一个 <p>（「你还有 N 次尝试机会」）与表格之间要留足间距，
   否则说明文字会紧贴卡片上沿，看着像卡片的一部分 */
#nav_block:has(> form > table[border]) > p:last-of-type {
    margin-bottom: var(--nx-space-6);
}

/* ---- 纯提示页（无表单）：signup.php 关闭注册时的「对不起」----
   ⚠️ 它与上面几个页面**结构不同**，实测：
        nav_block > table.main > tbody > tr > td.embedded > h2 + table[border="1"]
      表格**没有** form 包裹 → 上面的 `> form > table[border]` 一条都命不中，
      截图里就是个刺眼的白底方框（白框+直角+文字贴边）。
   所以这里必须用**另一条同构判据**再开一段：`> table > tbody > tr > td.embedded`。
   仍然不是全局规则 —— 只有「nav_block 直接子表格里带 td.embedded」才算，
   正常导航页没有这种结构。 */
#nav_block:has(> table > tbody > tr > td.embedded) > table {
    width: 100% !important;   /* 页面写死 width="500"/class="main" 会缩成窄条 */
}
#nav_block:has(> table > tbody > tr > td.embedded) > table > tbody > tr > td.embedded {
    padding: var(--nx-space-6) var(--nx-space-5) !important;
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-md);
    text-align: left;
}
#nav_block:has(> table > tbody > tr > td.embedded) > table > tbody > tr > td.embedded > h2 {
    margin: 0 0 var(--nx-space-4);
    font-size: var(--nx-font-xl);
    font-weight: var(--nx-weight-bold);
    color: var(--nx-text);
}
/* 内层那张裸提示表：去掉 border 属性画的亮白框，压成一块软底 */
#nav_block:has(> table > tbody > tr > td.embedded) > table > tbody > tr > td.embedded > table[border] {
    border: 0 !important;
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    background: var(--nx-surface-sunken);
    border-radius: var(--nx-radius-md);
    overflow: hidden;
}
#nav_block:has(> table > tbody > tr > td.embedded) > table > tbody > tr > td.embedded > table[border] > tbody > tr > td {
    padding: var(--nx-space-4) !important;
    border: 0 !important;
    font-size: var(--nx-font-base);
    line-height: 1.85;
    color: var(--nx-text-secondary);
}

/* ---- 表单卡：把裸表格变成一张居中卡片 ---- */
#nav_block:has(> form > table[border]) > form {
    display: block;
    max-width: 480px;
    margin: 0 auto;
}
#nav_block:has(> form > table[border]) > form > table[border] {
    /* ⚠️ border 属性画的是「表格外框 + 每个单元格框」，必须在 CSS 里关掉，
       否则会跟下面的圆角卡片叠出双重边框 */
    border: 0 !important;
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-md);
    overflow: hidden;   /* 让首/末行的底色被卡片圆角裁切 */
}
/* 每行统一内边距；左右给足，避免标签贴边 */
#nav_block:has(> form > table[border]) > form > table[border] > tbody > tr > td {
    padding: var(--nx-space-3) var(--nx-space-4);
    border: 0;
    vertical-align: middle;
}
/* 标签列（注册邮箱 / 验证图片 / 验证码）：右对齐、定宽，与 login 页一致 */
#nav_block:has(> form > table[border]) > form > table[border] > tbody > tr > td.rowhead {
    width: 96px;
    background: transparent;
    text-align: right;
    white-space: nowrap;
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text-secondary);
}
/* 字段列：吃掉剩余宽度，别让表格按内容收缩 */
#nav_block:has(> form > table[border]) > form > table[border] > tbody > tr > td.rowfollow {
    width: auto;
    background: transparent;
}
/* 行之间的细分隔线（末行除外，它自己是一条操作区） */
#nav_block:has(> form > table[border]) > form > table[border] > tbody > tr + tr > td {
    border-top: var(--nx-border-thin) solid var(--nx-border) !important;
}

/* ---- 输入框 ---- */
#nav_block:has(> form > table[border]) input[type="text"],
#nav_block:has(> form > table[border]) input[type="password"] {
    /* ⚠️ 页面里有内联 `style="width: 150px"`，内联优先级最高 → 必须 !important 才盖得住。
       不盖的话输入框只有 150px 宽，右边空一大片（用户截图里的就是这个）。 */
    width: 100% !important;
    max-width: 100%;
    box-sizing: border-box;
    padding: var(--nx-space-2) var(--nx-space-3);
    font-size: var(--nx-font-base);
    color: var(--nx-text);
    background: var(--nx-surface-alt);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
#nav_block:has(> form > table[border]) input[type="text"]:focus,
#nav_block:has(> form > table[border]) input[type="password"]:focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
/* 验证码图片：给个描边圆角，别让它在卡片里显得突兀 */
#nav_block:has(> form > table[border]) img[alt="CAPTCHA"] {
    border-radius: var(--nx-radius-sm);
    border: var(--nx-border-thin) solid var(--nx-border);
    display: block;
}
/* ⚠️ 2026-09-19：验证码输入框与其它字段宽度必须一致。
   confirm_resend.php 的内联写的是 `style="width: 180px"`，而同一张表里
   邮箱/密码三格是 `width: 200px` → 验证码那格明显比上面窄一截（用户截图可见）。
   这里用 !important 压过内联（内联优先级最高，只能 !important 覆盖），
   宽高对齐后整列右边缘才是齐的。
   注意：width:100% 交给上面的通用规则，这里只保证不被内联的 180px 钉住。 */
#nav_block:has(> form > table[border]) input[name="imagestring"] {
    width: 100% !important;
    max-width: 100%;
    box-sizing: border-box;
}

/* ---- 操作区（确定按钮那一行）----
   与 login 页的按钮行同一套语言：沉一档的底 + 居中 */
#nav_block:has(> form > table[border]) > form > table[border] > tbody > tr > td.toolbox {
    background: var(--nx-surface-sunken) !important;
    text-align: center !important;
    padding: var(--nx-space-4) !important;
}
/* ⚠️ 按钮用 .btn（页面已带），这里只保证它在卡片里宽度不被拉伸得怪 */
#nav_block:has(> form > table[border]) td.toolbox .btn,
#nav_block:has(> form > table[border]) td.toolbox input[type="submit"] {
    min-width: 120px;
    cursor: pointer;
}

/* ══════════════════════════════════════════════════════════════════════════
   登录页（login.php）—— 左右分栏 + 眼睛跟随鼠标的动漫小人
   ══════════════════════════════════════════════════════════════════════════
   ⚠️ 登录页**没有 `#outer`**！实测它的 DOM 是
        body > table.mainouter > tr > td#nav_block.text
      （登录表单 #login-form 的父元素就是那个 td）
      所以这一段一律以注入类 .nx-login-wrap / .nx-login-art 作作用域 ——
      写成 `#outer ...` 在这里一条都不会生效。

   PHP 结构不动（登录页字段多，动结构风险大）：由 nexus.js 把
   #login-form 及其后的兄弟节点整体包进 .nx-login-wrap，并在前面插入
   .nx-login-art，于是形成 wrap > [art, form…] 的两栏。

   小人配色说明：那几个色块是**插画底色，刻意不随主题走**（卡通角色有固定形象），
   所以这里直接写死 hex；其余属于主题体系的部分（卡片/文字/边框/阴影）全走令牌。
   ══════════════════════════════════════════════════════════════════════ */

/* 「登录 / 注册」按钮对：2026-09-19 已从本处的裸文字链接改为 .nx-auth-btn（样式在 styles/nexus.css）。
   标记现包在 <span class="nx-auth-actions"> 内，不再是 #nav_block 的直接子级，故删掉原先的
   `#nav_block > a` 与 `:hover` 规则。新按钮同样全走 --nx-* 令牌，切主题 / 切明暗自动跟随。
   ⚠️ 遗留坑（日后改色留意）：base.css 的全局 `a { transition: color ... }` 在这里会踩 Chromium
   变量色不重算的问题——变量已变、计算值仍停在旧色。旧规则靠 `transition: none` 规避；
   .nx-auth-btn 只过渡背景/阴影/位移、不过渡 color，故不受影响。 */

#nav_block > .nx-login-wrap {
    display: flex;
    flex-wrap: wrap;          /* 表单下方的说明段落要换到下一行 */
    align-items: stretch;
    gap: var(--nx-space-7);
    max-width: 1000px;
    margin: var(--nx-space-7) auto var(--nx-space-6);
    text-align: left;
}

/* ---- 左：插画区 ---- */
.nx-login-art {
    /* 瞳孔位移由 nexus.js 用 style.setProperty 实时写入。这里给默认值：
       ① 让静态检查（check-css.php）不再报「未定义变量」；
       ② 把这对变量的用途写在定义处，免得后人以为是漏定义。 */
    --nx-pupil-x: 0px;
    --nx-pupil-y: 0px;
    position: relative;
    flex: 0 0 340px;
    min-height: 380px;
    border-radius: var(--nx-radius-lg);
    background: linear-gradient(160deg, #6b7280 0%, #4b5563 55%, #374151 100%);
    overflow: hidden;
}

/* 小人：底部对齐的圆头色块 */
.nx-art-figure {
    position: absolute;
    bottom: 58px;                 /* 别贴底边，视觉重心更稳 */
    border-radius: 999px 999px 0 0;
    transition: transform var(--nx-dur-slow) var(--nx-ease-spring);
}
/* 四个角色整体在 340px 宽的插画区里居中（原值偏左，右上方会空一大块） */
.nx-art-figure--a { left: 62px;  width: 76px;  height: 198px; background: #8b5cf6; z-index: 1; }
.nx-art-figure--b { left: 126px; width: 88px;  height: 134px; background: #1f2937; z-index: 3; }
.nx-art-figure--c { left: 30px;  width: 106px; height: 86px;  background: #f0a17a; z-index: 2; }
.nx-art-figure--d { left: 204px; width: 94px;  height: 114px; background: #f5e07a; z-index: 2; }

/* 眼球与瞳孔（瞳孔靠 --nx-pupil-x/y 位移，由 nexus.js 实时写入） */
.nx-eye {
    position: absolute;
    display: block;
    background: #fff;
    border-radius: 50%;
}
.nx-pupil {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 44%;
    height: 44%;
    margin: -22% 0 0 -22%;
    background: #111827;
    border-radius: 50%;
    transform: translate(var(--nx-pupil-x, 0px), var(--nx-pupil-y, 0px));
    transition: transform 70ms linear;
}
/* 各角色的眼睛位置 */
.nx-art-figure--a .nx-eye { width: 16px; height: 16px; top: 24px; }
.nx-art-figure--a .nx-eye:nth-of-type(1) { left: 14px; }
.nx-art-figure--a .nx-eye:nth-of-type(2) { left: 44px; }
.nx-art-figure--b .nx-eye { width: 18px; height: 18px; top: 20px; }
.nx-art-figure--b .nx-eye:nth-of-type(1) { left: 16px; }
.nx-art-figure--b .nx-eye:nth-of-type(2) { left: 50px; }
.nx-art-figure--c .nx-eye { width: 11px; height: 11px; top: 30px; }
.nx-art-figure--c .nx-eye:nth-of-type(1) { left: 26px; }
.nx-art-figure--c .nx-eye:nth-of-type(2) { left: 54px; }
.nx-art-figure--d .nx-eye { width: 14px; height: 14px; top: 26px; }
.nx-art-figure--d .nx-eye:nth-of-type(1) { left: 20px; }
.nx-art-figure--d .nx-eye:nth-of-type(2) { left: 52px; }
/* 黄角色的嘴 */
.nx-art-mouth {
    position: absolute;
    left: 30px;
    top: 66px;
    width: 24px;
    height: 3px;
    border-radius: 2px;
    background: #111827;
}
/* 黑角色的眉毛 */
.nx-art-brow {
    position: absolute;
    top: 10px;
    width: 16px;
    height: 3px;
    border-radius: 2px;
    background: #e5e7eb;
}
.nx-art-brow:nth-of-type(3) { left: 17px; }
.nx-art-brow:nth-of-type(4) { left: 51px; }

/* 聚焦密码框时：小人们"扭头不看"（瞳孔移向一侧 + 身体略侧倾） */
.nx-login-art.is-shy .nx-pupil {
    transform: translate(calc(var(--nx-pupil-x, 0px) * 0.35 - 3px), calc(var(--nx-pupil-y, 0px) * 0.35));
}
.nx-login-art.is-shy .nx-art-figure { transform: translateY(3px) rotate(-3deg); }

/* ---- 右：表单卡 ---- */
.nx-login-wrap > #login-form {
    flex: 1 1 auto;
    min-width: 0;
    padding: var(--nx-space-6) var(--nx-space-7);
    background: var(--nx-surface);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-lg);
    box-shadow: var(--nx-shadow-md);
}
/* 把老式表格摊平成行式布局 */
#login-form > table { display: block; width: 100%; border-collapse: collapse; }
#login-form > table > tbody { display: block; }
#login-form > table > tbody > tr {
    display: flex;
    align-items: center;
    gap: var(--nx-space-4);
    padding: var(--nx-space-2) 0;
}
#login-form > table > tbody > tr > td { display: block; padding: 0; border: 0; }
/* 带 colspan 的行（高级选项标题、验证码、按钮行）保持整行 */
#login-form > table > tbody > tr:has(> td[colspan]) { display: block; }
#login-form td.rowhead {
    flex: 0 0 98px;
    background: transparent;
    text-align: left;
    white-space: nowrap;
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text-secondary);
}
/* ⚠️ 曾把这里改成 display:flex 想让验证码框拉伸铺满，
   结果整个分栏塌成了上下堆叠 —— flex 容器的 min-content 变大，
   把 .nx-login-wrap 的换行（art 340px + form）撑开了。
   验证码框比别的框短是小事，分栏塌掉是大事，已回退。
   真要修那格的宽度，应该单独限定到「含 hidden 的那一格」，别动整类 td。 */
#login-form td.rowfollow { flex: 1 1 auto; width: auto; }
#login-form input[type="text"],
#login-form input[type="password"] {
    width: 100% !important;
    box-sizing: border-box;
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-base);
    color: var(--nx-text);
    background: var(--nx-surface-alt);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    transition: border-color var(--nx-dur-fast) var(--nx-ease-out),
                box-shadow var(--nx-dur-fast) var(--nx-ease-out);
}
#login-form input[type="text"]:focus,
#login-form input[type="password"]:focus {
    outline: none;
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
/* 密码框右侧留出「显示/隐藏密码」按钮的位置。
   ⚠️ 这里必须按「父格里有按钮」来匹配，不能写 input[type="password"] ——
      点了显示之后 type 会变成 text，按 type 匹配会在那一瞬间丢掉右内距，
      文字就被按钮压住了。 */
#login-form td:has(> .nx-pwd-toggle) > input[type="text"],
#login-form td:has(> .nx-pwd-toggle) > input[type="password"] {
    padding-right: 38px !important;
}
#login-form .nx-pwd-toggle {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    color: var(--nx-text-tertiary);
    background: transparent;
    border: 0;
    border-radius: var(--nx-radius-sm);
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
}
#login-form .nx-pwd-toggle:hover {
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
}
#login-form .nx-pwd-toggle.is-on { color: var(--nx-primary-strong); }
/* ── 按钮区（2026-09-18 重做）────────────────────────────────────────────
   用户反馈三件事：①「登录/注册」离上方那条边框太近，像直接贴着；
                 ②登录/注册按钮不好看，想要图标；
                 ③重置按钮颜色该优化。

   根因（①）：按钮行是 <td class="toolbox">，它既是「高级选项」小标题的样式，
       又是按钮行的样式。旧规则给末行 padding-top:16px 却没有下内边距
       （下方靠 td 自身的 padding-bottom:4px），而上方「高级选项」栏带一条
       border-bottom 分隔线 —— 于是按钮就死死顶在那条线下方，且离卡片底边
       只剩几个像素。观感就是「贴着上个边框」。
   修法：给末行一个对称、充足的内边距，并用 border-top 把按钮区从表单字段里
       切出来（视觉上分区），而不是任由它贴在上一条分隔线下面。
   ────────────────────────────────────────────────────────────────────── */

/* 主按钮：登录（老代码是 input[type=button]#submit-btn） */
#login-form #submit-btn,
#login-form input.btn[type="submit"] {
    position: relative;
    min-width: 118px;
    /* 左内距加大，给图标留位（图标由下面的 background-image 画，见注释） */
    padding: var(--nx-space-3) var(--nx-space-6) var(--nx-space-3) 42px !important;
    font-family: var(--nx-font-sans);
    font-size: var(--nx-font-md);
    font-weight: var(--nx-weight-semibold);
    letter-spacing: 0.02em;
    color: #fff !important;
    /* 用品牌渐变而非单色，按钮更"立"起来；--nx-gradient-brand 在共享层
       schemes.css 里随配色方案走（深海蓝/翡翠青/琥珀金各有取值），
       兜底回落到 --nx-primary，旧主题没这个变量也不会塌。

       ⚠️ 图标画法（2026-09-18 实测后改定）：
       最初用 `::before { content:"\f2f6" }` 挂 Font Awesome 字体图标，
       **Chromium 不会在 <input> 上渲染伪元素**（input 是替换元素）——
       计算样式里 content/font-family 全对，字体也确认已加载
       （document.fonts 里 "Font Awesome 5 Free|900" 状态为 loaded），
       但就是不画出来。对照实验：同一个字形放在 <span> 里能量到 16×16px。
       所以这里改用 **background-image + 内联 SVG**（背景图在 <input> 上正常）。
       参数是 Font Awesome 5.15.4 的 svgs/solid/sign-in-alt.svg 原始 path，
       颜色写死 #fff —— 主按钮底是彩色渐变，白色图标本就与主题无关，合理。
       若哪天要跟着主题走，请改用 mask-image（但那会连渐变一起被遮掉，不行）。 */
    background-color: var(--nx-primary) !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23fff' d='M416 448h-84c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h84c17.7 0 32-14.3 32-32V160c0-17.7-14.3-32-32-32h-84c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h84c53 0 96 43 96 96v192c0 53-43 96-96 96zm-47-201L201 79c-15-15-41-4.5-41 17v96H24c-13.3 0-24 10.7-24 24v96c0 13.3 10.7 24 24 24h136v96c0 21.5 26 32 41 17l168-168c9.3-9.4 9.3-24.6 0-34z'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: 20px 50% !important;
    background-size: 15px 15px !important;
    border: var(--nx-border-thin) solid transparent !important;
    border-radius: var(--nx-radius-md);
    box-shadow: var(--nx-shadow-sm);
    cursor: pointer;
    transition: box-shadow var(--nx-dur-fast) var(--nx-ease-out),
                filter var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
#login-form #submit-btn:hover,
#login-form input.btn[type="submit"]:hover {
    filter: brightness(1.12);
    box-shadow: var(--nx-shadow-md);
    transform: translateY(-1px);
}
#login-form #submit-btn:active,
#login-form input.btn[type="submit"]:active {
    filter: brightness(0.94);
    box-shadow: var(--nx-shadow-xs);
    transform: translateY(0);
}
#login-form #submit-btn:focus-visible,
#login-form input.btn[type="submit"]:focus-visible {
    outline: none;
    box-shadow: var(--nx-shadow-focus);
}

/* 次按钮：重置。
   ⚠️ 旧版是 `background: transparent` + `border: --nx-border` —— 在深色面上
   几乎看不出是个按钮（用户反馈「重置按钮颜色是否要优化」）。
   改成「有底色 + 描边 + hover 变主色」的正经次按钮。
   图标同样走内联 SVG；这里底色是**单色**（--nx-surface-alt），
   所以可以用 **mask-image + background-color: currentColor** 让图标跟着
   文字色/主题走 —— 单色底不怕被遮，比写死颜色更好。
   为保险起见加一条 background-image 兜底（不支持 mask 的环境仍有图标）。 */
#login-form input[type="reset"] {
    min-width: 104px;
    padding: var(--nx-space-3) var(--nx-space-5) var(--nx-space-3) 40px !important;
    font-family: var(--nx-font-sans);
    font-size: var(--nx-font-md);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text-secondary) !important;
    background-color: var(--nx-surface-alt) !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath fill='%23a3b4d0' d='M255.545 8c-66.269.119-126.438 26.233-170.86 68.685L48.971 40.971C33.851 25.851 8 36.559 8 57.941V192c0 13.255 10.745 24 24 24h134.059c21.382 0 32.09-25.851 16.971-40.971l-41.75-41.75c30.864-28.899 70.801-44.907 113.23-45.273 92.398-.798 170.283 73.977 169.484 169.442C423.236 348.009 349.816 424 256 424c-41.127 0-79.997-14.678-110.63-41.556-4.743-4.161-11.906-3.908-16.368.553L89.34 422.659c-4.872 4.872-4.631 12.815.482 17.433C133.798 479.813 192.074 504 256 504c136.966 0 247.999-111.033 248-247.998C504.001 119.193 392.354 7.755 255.545 8z'/%3E%3C/svg%3E") !important;
    background-repeat: no-repeat !important;
    background-position: 18px 50% !important;
    background-size: 14px 14px !important;
    border: var(--nx-border-thin) solid var(--nx-border-strong) !important;
    border-radius: var(--nx-radius-md);
    cursor: pointer;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
#login-form input[type="reset"]:hover {
    color: var(--nx-primary-strong) !important;
    /* ⚠️ 必须用 background-color 而不是 background 简写 ——
       简写会把上面设的 background-image（图标）一起重置成 none，
       表现为「鼠标一放上去图标就消失」。 */
    background-color: var(--nx-primary-soft) !important;
    border-color: var(--nx-primary-border) !important;
    transform: translateY(-1px);
}
#login-form input[type="reset"]:active { transform: translateY(0); }
#login-form input[type="reset"]:focus-visible {
    outline: none;
    border-color: var(--nx-primary) !important;
    box-shadow: var(--nx-shadow-focus);
}

/* 图标（已改为 background-image 内联 SVG，规则写在上面的按钮定义里）。
   ⚠️ 曾经这里用 `::before { content: "\f2f6" }` 挂 Font Awesome 字体图标，
       **已验证在 Chromium 上完全不渲染** —— input 是替换元素，不画伪元素。
       （证据：计算样式 content/font-family/font-weight 全部正确，
         document.fonts 里 "Font Awesome 5 Free|900" 状态为 loaded，
         同一字形放进 <span> 能量到 16×16px，唯独 input 上不见图形。）
       故删除，改走 background-image。留此注释避免后人再踩。 */

/* 「高级选项：」小标题行（td.toolbox colspan=2）与末行按钮行，
   都由「靠边框线划分的透明行」升级为**圆角软面板**（2026-09-18 用户要求）。

   ⚠️ 为什么必须同时给底色，圆角才有意义：
      原本这两行 background: transparent + 只有一条 border-bottom/top，
      圆角加在「透明的东西」上是看不见的 —— 圆角只有配合**面**（背景/描边）
      才形成可见的轮廓。所以本次是「软面 + 圆角」一起上，不是单纯加圆角。

   ⚠️ 为什么能用圆角：`#login-form > table > tbody > tr > td { display: block }`
      （见上方 2289 行）把每个 td 都块级化了，圆角不会被表格布局切掉。

   ⚠️ 必须显式 `width: 100%` + `box-sizing: border-box`：
      td 虽然 display:block，但浏览器仍保留表格单元格的「按内容收缩」倾向，
      面板会缩成一条比卡片窄的短条、按钮还会溢出到右边缘。
      box-sizing 不能少 —— 否则 width:100% 再加左右内边距会横向溢出。 */
#login-form td.toolbox {
    display: block;
    width: 100%;
    box-sizing: border-box;
    background: var(--nx-surface-alt);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    padding: var(--nx-space-3) var(--nx-space-4) !important;
    /* ⚠️ 这里必须显式 left：继承来的右对齐会让「高级选项：」跑到面板右边 */
    text-align: left;
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    color: var(--nx-text-secondary);
    letter-spacing: 0.03em;
}
/* 末行（登录 / 重置 按钮那一行）同样是 toolbox，但语义是「操作区」，
   所以用更沉一档的面 + 居中偏右的排布，与外层卡片形成层次。
   ⚠️ 这里也是用户最初说的「挨着上个边框」的地方：
      旧规则 padding-top: 16px + border-bottom: 0，上一行又带 border-bottom，
      于是按钮距线只有 16px、距卡片底边几乎为 0。
      现在两行各自成面板，中间靠 margin 拉开，不再依赖「贴着一条线」。 */
#login-form > table > tbody > tr:last-child > td.toolbox {
    margin-top: var(--nx-space-5);
    padding: var(--nx-space-5) var(--nx-space-4) !important;
    text-align: right;
    background: var(--nx-surface-sunken);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    /* 与上面工具箱同理：显式定宽 + border-box，否则按钮会溢出右边缘 */
    display: block;
    width: 100%;
    box-sizing: border-box;
}
/* 按钮之间留出明确的间隔（原来只靠一个空格字符，约 4px） */
#login-form #submit-btn { margin-right: var(--nx-space-3) !important; }
/* 「高级选项」标题可点击折叠（行为见 nexus.js 的 nxAdvancedToggle）。
   用一个纯 CSS 三角做指示箭头：展开时朝下、折叠时朝右。 */
#login-form td.nx-adv-title {
    cursor: pointer;
    user-select: none;
    transition: color var(--nx-dur-fast) var(--nx-ease-out);
}
#login-form td.nx-adv-title:hover { color: var(--nx-primary-strong); }
#login-form td.nx-adv-title::before {
    content: "";
    display: inline-block;
    width: 0;
    height: 0;
    margin-right: var(--nx-space-2);
    border-left: 5px solid currentColor;
    border-top: 4px solid transparent;
    border-bottom: 4px solid transparent;
    transform: rotate(90deg);            /* 展开：箭头朝下 */
    transition: transform var(--nx-dur-fast) var(--nx-ease-out);
    vertical-align: 1px;
}
#login-form td.nx-adv-title.is-collapsed::before {
    transform: rotate(0deg);             /* 折叠：箭头朝右 */
}
/* 表单下方的说明段落（OAuth / 注册 / 忘记密码）：
   它们被一起收进 wrap，必须独占一行，否则会跟表单卡并排挤在一起 */
.nx-login-wrap > p {
    flex: 1 1 100%;
    margin: var(--nx-space-2) 0 0;
    /* 居中显示：wrap 自身是 text-align:left（表单里必须左对齐），
       这里显式改回 center，否则「申诉通道 / 还没有账号」会挤在左边 */
    text-align: center;
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
    line-height: 2;                 /* 段落里嵌了按钮，行高给足免得被裁 */
}
.nx-login-wrap > p:first-of-type { margin-top: var(--nx-space-5); }

/* ── 「注册」按钮化（2026-09-18 用户要求）──────────────────────────────
   原文案是 `还没有账号? 马上<a href="signup.php"><b>注册</b></a>！`，
   纯文字内联链接，视觉上与「忘记密码」「账号被禁用」几条毫无区别、
   也看不出是可点的注册入口。这里把那个链接做成**带图标的药丸按钮**，
   与表单里的主/次按钮形成一套体系。

   ⚠️ 用 `a[href*="signup.php"]` 而不是 `a[href="signup.php"]`：
      NexusPHP 输出的链接常是**绝对 URL**（get_protocol_prefix()+$BASEURL），
      前缀/全等匹配会漏。`*=` 才稳。
   ⚠️ 只作用于 .nx-login-wrap 内的，别误伤顶部导航里的注册链接。 */
.nx-login-wrap > p a[href*="signup.php"],
.nx-login-wrap > p a[href*="recover.php"],
.nx-login-wrap > p a[href*="user-ban-log.php"],
.nx-login-wrap > p a[href*="confirm_resend.php"] {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-2);
    /* 负外边距抵消 line-height 带来的额外高度，让按钮视觉上贴合文字基线 */
    margin: 0 var(--nx-space-1);
    padding: var(--nx-space-2) var(--nx-space-4);
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    line-height: 1.5;
    text-decoration: none !important;
    border-radius: var(--nx-radius-full);
    /* ⚠️ 刻意不过渡 color：base.css 的全局 `a { transition: color … }` 在这里会踩
       Chromium 的变量色不重算问题 —— 切 data-nx-theme 后 --nx-text-secondary 已经是新值，
       但计算出的 color 仍停在旧值（实测切到浅色后「邮件」还留着深色档的 #a3b4d0）。
       用户反馈的「邮件这个不会随着主题切换更改颜色」就是它；去掉 color 过渡即可。 */
    transition: background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out),
                transform var(--nx-dur-fast) var(--nx-ease-out);
}
/* 注册：主色描边药丸 + 人形加号图标 */
.nx-login-wrap > p a[href*="signup.php"] {
    color: var(--nx-primary-strong) !important;
    background-color: var(--nx-primary-soft);
    border: var(--nx-border-thin) solid var(--nx-primary-border);
}
.nx-login-wrap > p a[href*="signup.php"]:hover {
    color: var(--nx-on-primary) !important;
    background-color: var(--nx-primary) !important;
    border-color: var(--nx-primary) !important;
    transform: translateY(-1px);
}
/* 图标交给 Font Awesome：glyph 继承外层 a 的 color，切主题时和文字一起变。
   原先是 data-URI SVG，fill 写死 %2358a6ff，换到浅色底上几乎看不见。 */
.nx-login-wrap > p a[href*="signup.php"]::before {
    content: "\f234";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 0.86em;
    line-height: 1;
}
/* 找回密码：中性描边药丸 + 信封图标（次要入口，不抢注册的视觉） */
.nx-login-wrap > p a[href*="recover.php"],
.nx-login-wrap > p a[href*="user-ban-log.php"],
.nx-login-wrap > p a[href*="confirm_resend.php"] {
    color: var(--nx-text-secondary) !important;
    background-color: var(--nx-surface-alt);
    border: var(--nx-border-thin) solid var(--nx-border-strong);
}
.nx-login-wrap > p a[href*="recover.php"]:hover,
.nx-login-wrap > p a[href*="user-ban-log.php"]:hover,
.nx-login-wrap > p a[href*="confirm_resend.php"]:hover {
    color: var(--nx-primary-strong) !important;
    background-color: var(--nx-primary-soft) !important;
    border-color: var(--nx-primary-border) !important;
    transform: translateY(-1px);
}
/* 信封同上，用 FA 跟随 currentColor */
.nx-login-wrap > p a[href*="recover.php"]::before {
    content: "\f0e0";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 0.86em;
    line-height: 1;
}
/* 2026-09-19 补齐：封禁记录 / 重新发送验证邮件 也纳入同一套药丸 */
.nx-login-wrap > p a[href*="user-ban-log.php"]::before {
    content: "\f05e";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 0.86em;
    line-height: 1;
}
.nx-login-wrap > p a[href*="confirm_resend.php"]::before {
    content: "\f1d8";
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 0.86em;
    line-height: 1;
}
/* 药丸内的 <b> 只是历史标记，样式交给外层 a，避免字重叠加过粗 */
.nx-login-wrap > p a[href*="signup.php"] b,
.nx-login-wrap > p a[href*="recover.php"] b,
.nx-login-wrap > p a[href*="user-ban-log.php"] b,
.nx-login-wrap > p a[href*="confirm_resend.php"] b {
    font-weight: inherit;
    color: inherit;
}

/* ── 第三方验证码容器（Turnstile / hCaptcha，2026-09-18 新增）────────────
   include/functions.php 的 show_image_code() 起第三方驱动时，
   会输出 <div class="cf-turnstile nx-turnstile"> 或 <div class="h-captcha nx-hcaptcha">。

   ⚠️ 只做「外框对齐」，别去改内部结构：
      widget 的 DOM 是第三方脚本**运行时注入**的（iframe + 若干 div），
      我们写 CSS 时它还不存在；就算写了，对方也会用内联样式/自己的一套类名，
      我们的选择器进不去、进去了也压不过。所以这里只管两件事：
        ① 容器外距 —— 融进表单的行列节奏，别贴着上一行
        ② 空状态占位 —— 脚本还没加载完时别让布局跳一下
   ⚠️ data-size="flexible" 会让 widget 宽度跟随容器；容器必须是块级且
      有明确宽度，否则它会退化成 300px 固定宽、与输入框对不齐。

   ⚠️⚠️ 2026-09-19 实测踩坑（两处，都必须保留）：
      ① **min-width: 300px 不能省**。容器曾被浏览器算成宽度 0，于是 Turnstile
         连 iframe 都不注入，表现就是「验证码区域一片空白、登录卡住」。
         根因是循环依赖：show_image_code() 输出的是 `<td align="left">`（无 class），
         td 宽度由内容决定；而容器写 width:100% 是「取父级宽度的百分比」——
         父级宽度取决于内容、内容宽度取决于父级，浏览器解不出来就按 0 处理。
         破局点是给容器一个确定的下限宽度（300px 正是 widget 的标准宽度）。
      ② **背景必须透明**。widget 自己那一区块是浅色的（Turnstile 固定白底，
         dark 模式下也一样），但容器是整个 td 宽（如 476px），
         给它刷任何不透明底色都会在 widget 右侧露出一条刺眼的色带。
         实测症状：confirm_resend.php 上出现一个 476×60 的纯白方块，
         而周围是深色卡片 —— 与上方三格输入框格格不入。
         正解是容器**完全不出手**，只做宽度/外距，颜色交给 widget 自己。*/
.nx-turnstile,
.nx-hcaptcha {
    display: block;
    /* 铺满整列，与上面的用户名/密码输入框同宽 —— 用户要求「验证框在各尺寸下
       和输入框对齐」。输入框是 td.rowfollow(flex:1 1 auto) 里的 width:100%，
       所以这里也 width:100%，并让承载它的 td 用同样的 flex 尺寸（见下方 :has 规则），
       两者左右边缘在每个断点都齐平。
       ⚠️ widget 本体在跨域 shadow DOM 的 iframe 里（document 里查不到 iframe、
          但无障碍树能看到「包含 Cloudflare 安全质询的小组件」），它的边框色/圆角/
          背景由 Cloudflare 控制，我们的 CSS 进不去；外层只能调宽度与对齐，配色交给
          data-theme(auto/light/dark)。拉宽后右侧 logo 显得空是第三方固有表现，改不了。 */
    width: 100%;
    /* 300px 是 widget 能渲染的下限：低于它 Cloudflare 不再注入 iframe */
    min-width: 300px;
    /* 窄屏兜底，别横向溢出卡片 */
    max-width: 100%;
    /* 脚本加载前的占位高度，避免「加载完成瞬间整页往下跳」 */
    min-height: 65px;
    margin: var(--nx-space-1) 0 var(--nx-space-2);
    /* ⚠️ 绝不能给背景色：会从 widget 右侧漏出来变成一条色带。
       widget 未加载时这块是「空气」，本来就该透出卡片的底色。 */
    background: transparent none;
    overflow: hidden;
}
/* 第三方在窄屏下会自己缩，这里兜底保证不横向溢出 */
.nx-turnstile iframe,
.nx-hcaptcha iframe {
    max-width: 100% !important;
    border-radius: var(--nx-radius-sm);
}

/* ── 验证码那一格（承载 widget 的那个 td）宽度 ──────────────────────────
   图片验证码与第三方 widget 都渲染在第二个 td 里；图片只有 180px 宽，
   第三方 widget 想铺满 —— 所以只在「td 的直接子就是 widget 容器」时拉满宽度。

   ⚠️ 2026-09-19 修 bug：这里原本写的是 `#login-form td.rowfollow:has(...)`，
      但 show_image_code() 在第三方分支输出的是**无 class 的裸 td**
      （`<td align="left">`），那条规则从未命中过 ——
      于是不管怎么调容器样式，宽度始终是坏的。改成不限页面、不限类的写法。

   ⚠️ 用 :has() 精确限定，别改整类 td（见上方 2301 行的踩坑记录：
      整类改成 flex 会把 .nx-login-wrap 的分栏撑塌）。 */
td:has(> .nx-turnstile),
td:has(> .nx-hcaptcha) {
    /* 与同行 #login-form td.rowfollow 用完全相同的弹性尺寸，保证验证框的
       左右边缘和用户名/密码输入框在每个断点都齐平；min-width:0 防止内容把列
       撑宽导致分栏塌陷。非 flex 的行式布局里 flex 无效、width:100% 仍生效，安全。 */
    flex: 1 1 auto;
    min-width: 0;
    width: 100%;
}

/* 窄屏：插画缩到顶部，表单占满 */
@media (max-width: 900px) {
    #nav_block > .nx-login-wrap { flex-direction: column; gap: var(--nx-space-5); }
    .nx-login-art { flex: 0 0 auto; min-height: 220px; }
    .nx-login-art .nx-art-figure { transform: scale(0.82); transform-origin: bottom center; }
}

/* ══════════════════════════════════════════════════════════════════════════
   控制面板导航（usercp.php）
   ──────────────────────────────────────────────────────────────────────────
   结构（`usercp.php:15` 的 usercpmenu()）：
     <div id="usercpnav"><ul id="usercpmenu" class="menu">
       <li class="selected"><a href="usercp.php">设定首页</a></li>
       <li><a href="?action=personal">个人设定</a></li>
       <li><a href="?action=tracker">网站设定</a></li>
       <li><a href="?action=forum">论坛设定</a></li>
       <li><a href="?action=security">安全设定</a></li>

   原来**一条样式都没有**，就是浏览器默认的 ul + 圆点（截图确认）。
   改成横向分段标签：
     · 图标走 `::before` + mask（形状取 SVG、颜色取 `currentColor`）
       ⇒ 自动跟随主题、明暗、以及选中/悬停态，不必为每种状态各写一份
     · 选中项用主色实底 + 反白字，和未选中形成明确对比

   ⚠️ `ul` 的 class 是 `menu`，与主导航 `nav#nav ul.menu` 同名 ——
      所以这里一律以 `#usercpnav` 前缀限定，避免误伤主导航。
   ══════════════════════════════════════════════════════════════════════════ */

/* ⚠️ 这里**不要**用负边距去"对齐内容表格宽度"。
   上一版我写过 `margin: 0 -16px`，想让导航与下方内容表格同宽 ——
   结果把导航推出了 `td.embedded` 的内边距区，**第一个标签直接撞上白卡左边框**
   （用户截图反馈「设定首页和父级 div 边框重合了」）。
   真实情况是：导航在 `td.embedded`（左右各 16px padding 的白卡）**内部**，
   而内容表格在卡片**外部**，两者本来就属于不同的块、各有各的内边距。
   强行拉宽只会撞边框 —— 保持自然的容器内边距即可。 */
#usercpnav,
#lognav,
#pmboxnav {
    margin: 0 0 var(--nx-space-5);
}

/* ⚠️ usercp 的表单表格写死了 `width="1200"`，浏览器会**居中**它 ——
   视口 1600、白卡宽 1566 时，表格只有 1200 ⇒ 左边空出 183px
   （实测 rowhead "封存账号" 的 L=200，而白卡左缘才 17）。
   用户反馈「个人设定下面的信息栏左侧没完全靠左」就是这个。
   ⚠️ 第一次我用 `#outer table.main table[width="1200"]` 没命中
      （那张表不在 table.main 里，实测仍在 L=200），改用更宽的兜底选择器 +
      `!important`：写死 1200 的表在宽屏下本来就该拉满，不该居中留白。 */
#outer table[width="1200"] {
    width: 100% !important;
}

/* ══════════════════════════════════════════════════════════════════════════
   分类卡片（td.bottom）—— checkbox 位置
   ──────────────────────────────────────────────────────────────────────────
   ⚠️ 对齐**不在这里自己实现**，而是与搜索箱**共用同一套规则** ——
      见上面「搜索箱选项栅格」那一段（`#outer tr:has(> td.bottom) …`）。
      那套做法是：行改 flex、卡片 inline-flex、
      **checkbox 绝对定位到卡片左上角**（`left:5px; top:5px`），不占横向空间。

   ⚠️ 踩过的坑（记录以免重犯）：
      两套规则原先都带 `table.searchbox` 前缀，而「网站设置」页的表格
      **没有这个类** ⇒ 一条都不生效，那边的 checkbox 退回浏览器默认样式，
      与图标挤在一起、高低不一（用户两次反馈）。
      修法：把 14 处选择器里的 `table.searchbox ` 去掉，两处共用。
      —— 和前面 `span.nx-sb-label` 图标是**同一个原因**：
      **限定条件不该绑页面/容器的类名，该绑语义结构。**

      另外我曾在这里另写一套「checkbox 垂直居中 + padding-left」，
      与搜索箱的「左上角」做法**互相打架**（padding-left 还被压掉），已删除。
      **同一个组件只留一套规则。**
   ══════════════════════════════════════════════════════════════════════ */
/* 分类图标：统一圆角 */
#outer td.bottom > a > img {
    border-radius: var(--nx-radius-sm, 4px);
}

#usercpnav > ul#usercpmenu,
#lognav > ul#logmenu,
#pmboxnav > ul#pmboxmenu {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nx-space-2);
    list-style: none;
    margin: 0;
    padding: 0;
}
#usercpnav > ul#usercpmenu > li,
#lognav > ul#logmenu > li,
#pmboxnav > ul#pmboxmenu > li { margin: 0; }

#usercpnav ul#usercpmenu > li > a,
#lognav ul#logmenu > li > a,
#pmboxnav ul#pmboxmenu > li > a {
    display: inline-flex;
    align-items: center;
    gap: var(--nx-space-2);
    padding: var(--nx-space-3) var(--nx-space-4);
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-medium);
    color: var(--nx-text-secondary);
    /* ⚠️ 原用 `--nx-surface-alt`（浅色下 #f8fafc），而它所在的 td.embedded 是纯白 #ffffff ——
       两者只差 1% 亮度，标签背景几乎看不见边界，只剩一块「脏白块」（用户截图反馈）。
       改用 sunken（比白底明确深一档），再把描边交给 border 表达。 */
    background: var(--nx-surface-sunken);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-md);
    text-decoration: none;
    white-space: nowrap;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out),
                border-color var(--nx-dur-fast) var(--nx-ease-out);
}
/* 图标：形状取自 mask、颜色取自 currentColor ⇒ 跟随文字状态自动变化 */
#usercpnav ul#usercpmenu > li > a::before,
#lognav ul#logmenu > li > a::before,
#pmboxnav ul#pmboxmenu > li > a::before {
    content: "";
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    opacity: .9;
    -webkit-mask-repeat: no-repeat;   mask-repeat: no-repeat;
    -webkit-mask-position: center;    mask-position: center;
    -webkit-mask-size: contain;       mask-size: contain;
}

/* 悬停 */
#usercpnav ul#usercpmenu > li > a:hover,
#lognav ul#logmenu > li > a:hover,
#pmboxnav ul#pmboxmenu > li > a:hover {
    color: var(--nx-primary-strong);
    background: var(--nx-primary-soft);
    border-color: var(--nx-primary);
}
/* 当前页：主色实底 + 反白 */
#usercpnav ul#usercpmenu > li.selected > a,
#lognav ul#logmenu > li.selected > a,
#pmboxnav ul#pmboxmenu > li.selected > a {
    color: var(--nx-text-inverse);
    background: var(--nx-primary);
    border-color: var(--nx-primary);
    font-weight: var(--nx-weight-semibold);
}

/* ── 五个图标（Feather 风格线性，24×24 viewBox）────────────── */
/* ① 设定首页 —— 房子 */
#usercpnav ul#usercpmenu > li:nth-child(1) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 10.5 12 3l9 7.5'/><path d='M5.5 9.6V20a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1V9.6'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 10.5 12 3l9 7.5'/><path d='M5.5 9.6V20a1 1 0 0 0 1 1h11a1 1 0 0 0 1-1V9.6'/></svg>");
}
/* ② 个人设定 —— 用户 */
#usercpnav ul#usercpmenu > li:nth-child(2) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/><circle cx='12' cy='7' r='4'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'/><circle cx='12' cy='7' r='4'/></svg>");
}
/* ③ 网站设定 —— 滑杆 */
#usercpnav ul#usercpmenu > li:nth-child(3) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><line x1='4' y1='9' x2='20' y2='9'/><line x1='4' y1='15' x2='20' y2='15'/><circle cx='9' cy='9' r='2.4'/><circle cx='15' cy='15' r='2.4'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><line x1='4' y1='9' x2='20' y2='9'/><line x1='4' y1='15' x2='20' y2='15'/><circle cx='9' cy='9' r='2.4'/><circle cx='15' cy='15' r='2.4'/></svg>");
}
/* ④ 论坛设定 —— 对话气泡 */
#usercpnav ul#usercpmenu > li:nth-child(4) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8z'/></svg>");
}
/* ⑤ 安全设定 —— 盾牌 */
#usercpnav ul#usercpmenu > li:nth-child(5) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 2.8 4.5 6v6c0 4.6 3.2 8.4 7.5 9.6 4.3-1.2 7.5-5 7.5-9.6V6z'/><polyline points='9.2 12.2 11.3 14.3 15 10.6'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M12 2.8 4.5 6v6c0 4.6 3.2 8.4 7.5 9.6 4.3-1.2 7.5-5 7.5-9.6V6z'/><polyline points='9.2 12.2 11.3 14.3 15 10.6'/></svg>");
}

/* 窄屏：标签纵向堆叠，占满宽度 */
@media (max-width: 700px) {
    #usercpnav > ul#usercpmenu,
    #lognav > ul#logmenu,
    #pmboxnav > ul#pmboxmenu { flex-direction: column; }
    #usercpnav ul#usercpmenu > li > a,
    #lognav ul#logmenu > li > a,
    #pmboxnav ul#pmboxmenu > li > a { justify-content: flex-start; }
}


/* ══════════════════════════════════════════════════════════════════════════
   分类图标覆盖层 —— 统一风格的「圆角底 + 白色符号」现代图标
   ══════════════════════════════════════════════════════════════════════
   ⚠️ 本文件由脚本生成，不要手改（改脚本或直接改这里的 SVG 数据）。

   原始图标来自 `caticons` 表指向的 90×230 雪碧图
   （`pic/category/chd/scenetorrents/{chs,en}/catsprites.png`，每格 45×46），
   由 `catsprites.css` 用 background-position 定位 —— 那套图是像素化的位图，
   缩放会糊、深色底上发灰，故用本层覆盖。

   ⚠️ 两个必须注意的点：
     ① 选择器要 `#outer img.c_xxx`：`catsprites.css` 用的是 `img.c_xxx`，
        两者加载顺序不保证（catsprites 由 stdhead 注入），靠特异性压过更稳；
     ② `background-position` 必须 `!important`：否则会带着雪碧图偏移
        把新图裁掉一块。
   ══════════════════════════════════════════════════════════════════════ */

/* 统一的基础属性：圆角、居中、按容器缩放 */
img[class^="c_"] {
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: contain !important;
    border-radius: var(--nx-radius-sm, 4px);
}

img.c_movies { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%236366f1'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='14'%20y='17'%20width='17'%20height='12'%20rx='2.5'/%3E%3Cline%20x1='18.5'%20y1='17'%20x2='18.5'%20y2='29'/%3E%3Cline%20x1='26.5'%20y1='17'%20x2='26.5'%20y2='29'/%3E%3Cline%20x1='14'%20y1='23'%20x2='31'%20y2='23'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_doc { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%230d9488'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='12.5'%20y='18'%20width='14'%20height='10'%20rx='2.5'/%3E%3Cpath%20d='M26.5%2021.5%2032%2019v8l-5.5-2.5z'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_anime { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%23ec4899'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M22.5%2016.5l2.1%204.6%204.9.6-3.6%203.4.9%204.9-4.3-2.4-4.3%202.4.9-4.9-3.6-3.4%204.9-.6z'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_tvseries { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%233b82f6'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='13'%20y='17.5'%20width='19'%20height='11'%20rx='2.5'/%3E%3Cline%20x1='18'%20y1='32'%20x2='27'%20y2='32'/%3E%3Cline%20x1='22.5'%20y1='28.5'%20x2='22.5'%20y2='32'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_tvshows { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%238b5cf6'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='20'%20y='15.5'%20width='5'%20height='10'%20rx='2.5'/%3E%3Cpath%20d='M16.5%2022.5a6%206%200%200%200%2012%200'/%3E%3Cline%20x1='22.5'%20y1='28.5'%20x2='22.5'%20y2='32'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_mv { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%23f43f5e'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='18.5'%20cy='29'%20r='3'/%3E%3Ccircle%20cx='28'%20cy='26.5'%20r='2.6'/%3E%3Cline%20x1='21.5'%20y1='29'%20x2='21.5'%20y2='17'/%3E%3Cpath%20d='M21.5%2017l6.5-1.6v11.1'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_sports { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%23f59e0b'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M17%2016h11v6a5.5%205.5%200%200%201-11%200z'/%3E%3Cpath%20d='M17%2018h-3v1.5a3.5%203.5%200%200%200%203%203.4'/%3E%3Cpath%20d='M28%2018h3v1.5a3.5%203.5%200%200%201-3%203.4'/%3E%3Cline%20x1='22.5'%20y1='27.5'%20x2='22.5'%20y2='31'/%3E%3Cline%20x1='18'%20y1='31'%20x2='27'%20y2='31'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_misc { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%2364748b'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='16.5'%20cy='23'%20r='1.9'/%3E%3Ccircle%20cx='22.5'%20cy='23'%20r='1.9'/%3E%3Ccircle%20cx='28.5'%20cy='23'%20r='1.9'/%3E%3C/g%3E%3C/svg%3E") !important; }
img.c_hqaudio { background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2045%2046'%3E%3Crect%20x='1'%20y='1'%20width='43'%20height='44'%20rx='10'%20fill='%2310b981'/%3E%3Cg%20fill='none'%20stroke='%23ffffff'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M15%2025v-1.5a7.5%207.5%200%200%201%2015%200V25'/%3E%3Crect%20x='13'%20y='24.5'%20width='4.5'%20height='7'%20rx='2'/%3E%3Crect%20x='27.5'%20y='24.5'%20width='4.5'%20height='7'%20rx='2'/%3E%3C/g%3E%3C/svg%3E") !important; }

/* ══════════════════════════════════════════════════════════════
   D1c. 种子列表「评分 + 操作」图标主题化（2026-09-21）
   ──────────────────────────────────────────────────────────────
   用户反馈：种子列表右侧这几个图标「很不好看」。
   实测它们**完全没进设计系统**，还是上古位图素材：
     · 评分 = `pic/imdb2.png` / `pic/douban2.png` —— 整块纯黄 / 纯绿位图 logo，
       深色主题下像贴了一块黄胶布。由 `nexus/PTGen/PTGen.php:331` 输出，
       带内联 `max-width/max-height:16px`。
     · 下载 / 收藏 / 评论 = `sprites.css` 的 `img.download` / `img.delbookmark`
       / `img.bookmark` / `img.comments`，从 `png.png`、`icons.gif` 取格。

   延续 D1（分类图标）的做法：**只接管 background / mask，不动标记结构**。
   老主题（2/3/4/6/7/8）继续吃它们的位图；分层主题这边靠 !important 压过。

   ⚠️ 两个技术点（都不显然）：
     ① `<img>` 是**替换元素、不能挂 ::before/::after** —— 所以评分图标没法用
        伪元素重绘，只能用「`width:0` + `padding-left` 撑出显示区 + `background`
        画新图」这个经典替换法（`overflow:hidden` 把原来的位图裁掉）。
     ② 星标/下载/评论改用 **mask + background-color** —— 颜色就能走 `var(--nx-*)`
        令牌、跟着主题与配色方案变；若把颜色写进 data-URI 的 fill 里就写死了。
   ══════════════════════════════════════════════════════════════ */

/* ── 评分行（IMDb / 豆瓣 / bangumi / indienova）──────────────── */
div:has(> img[src*="imdb2.png"]),
div:has(> img[src*="douban2.png"]),
div:has(> img[src*="bangumi.jpg"]),
div:has(> img[src*="invienova.jpg"]) {
    display: flex !important;
    align-items: center !important;   /* 原内联写的是 align-content，对单行 flex 无效 */
    justify-content: space-between !important;
    gap: var(--nx-space-1, 4px) !important;
    padding: 2px 0 !important;
    line-height: 1 !important;
}

/* width:0 + padding-left ⇒ 原位图不显示，padding 区显示新背景 */
img[src*="imdb2.png"],
img[src*="douban2.png"],
img[src*="bangumi.jpg"],
img[src*="invienova.jpg"] {
    width: 0 !important;
    height: 16px !important;
    max-width: none !important;
    max-height: none !important;
    padding-left: 16px !important;
    box-sizing: content-box !important;
    overflow: hidden;
    flex: 0 0 auto;
    border-radius: 4px;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 16px 16px !important;
}

div:has(> img[src*="imdb2.png"]) > span,
div:has(> img[src*="douban2.png"]) > span,
div:has(> img[src*="bangumi.jpg"]) > span,
div:has(> img[src*="invienova.jpg"]) > span {
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm, 13px);
    font-variant-numeric: tabular-nums;
}

/* 品牌色圆角徽章 + 字母：保留品牌识别，但换成现代圆角方块 */
img[src*="imdb2.png"] {
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='4'%20fill='%23f5c518'/%3E%3Ctext%20x='8'%20y='8.6'%20text-anchor='middle'%20dominant-baseline='central'%20font-family='Helvetica,Arial,sans-serif'%20font-size='11'%20font-weight='700'%20font-style='italic'%20fill='%23111111'%3Ei%3C/text%3E%3C/svg%3E") !important;
}
img[src*="douban2.png"] {
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='4'%20fill='%232e9e4a'/%3E%3Ctext%20x='8'%20y='8.6'%20text-anchor='middle'%20dominant-baseline='central'%20font-family='PingFang%20SC,Microsoft%20YaHei,sans-serif'%20font-size='9.5'%20font-weight='600'%20fill='%23ffffff'%3E%E8%B1%86%3C/text%3E%3C/svg%3E") !important;
}
img[src*="bangumi.jpg"] {
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='4'%20fill='%23f09199'/%3E%3Ctext%20x='8'%20y='8.6'%20text-anchor='middle'%20dominant-baseline='central'%20font-family='Helvetica,Arial,sans-serif'%20font-size='9'%20font-weight='700'%20fill='%23ffffff'%3Ebgm%3C/text%3E%3C/svg%3E") !important;
}
img[src*="invienova.jpg"] {
    background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2016%2016'%3E%3Crect%20width='16'%20height='16'%20rx='4'%20fill='%233b82f6'/%3E%3Ctext%20x='8'%20y='8.6'%20text-anchor='middle'%20dominant-baseline='central'%20font-family='Helvetica,Arial,sans-serif'%20font-size='9'%20font-weight='700'%20fill='%23ffffff'%3EiN%3C/text%3E%3C/svg%3E") !important;
}

/* ── 下载 / 收藏 / 评论：mask + 令牌色 ──────────────────────────
   这几个是**雪碧图**（靠 background-position 取格），所以**不能改 width/height**
   —— 改了会漏出相邻帧的鬼影。只接管 background-image/position，
   再用 mask 把「一块令牌色」裁成图标形状。 */
/* ⚠️ 这里**只处理 download / bookmark / delbookmark**。
   `img.comments`（表头评论数）在本文档上方 277~298 行**早已有**一套
   `table.torrents img.comments` 的 mask 方案（对话气泡），特异性 (0,2,1)
   高于这里的 (0,1,1) —— 重复写只会被覆盖，所以不重复。
   ⚠️ `max-width: none` 不能省：全局 `img { max-width: 100% }` 会在窄列里
   把这些 16px 图标压成 13px，mask 跟着缩，图标就缺边（实测盒子 13×16）。 */
img.download, img.bookmark, img.delbookmark {
    background-image: none !important;
    background-position: center !important;
    max-width: none !important;
    -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
    -webkit-mask-position: center;  mask-position: center;
    -webkit-mask-size: contain;     mask-size: contain;
}

img.download {
    background-color: var(--nx-primary) !important;
    -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M12%203.5v11'/%3E%3Cpath%20d='M7.5%2010.5%2012%2015l4.5-4.5'/%3E%3Cpath%20d='M4.5%2017.5v1.5a1.5%201.5%200%200%200%201.5%201.5h12a1.5%201.5%200%200%200%201.5-1.5v-1.5'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2.2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M12%203.5v11'/%3E%3Cpath%20d='M7.5%2010.5%2012%2015l4.5-4.5'/%3E%3Cpath%20d='M4.5%2017.5v1.5a1.5%201.5%200%200%200%201.5%201.5h12a1.5%201.5%200%200%200%201.5-1.5v-1.5'/%3E%3C/svg%3E");
}
img.download:hover { background-color: var(--nx-primary-strong) !important; }

img.delbookmark {
    background-color: var(--nx-text-tertiary, #94a3b8) !important;
    -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M12%203.2l2.7%205.5%206%20.9-4.35%204.24%201.03%206L12%2017.03%206.62%2019.84l1.03-6L3.3%209.6l6-.9z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%23000'%20stroke-width='2'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M12%203.2l2.7%205.5%206%20.9-4.35%204.24%201.03%206L12%2017.03%206.62%2019.84l1.03-6L3.3%209.6l6-.9z'/%3E%3C/svg%3E");
}
img.delbookmark:hover { background-color: var(--nx-primary) !important; }

img.bookmark {
    background-color: var(--nx-warning, #f59e0b) !important;
    -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='%23000'%3E%3Cpath%20d='M12%203.2l2.7%205.5%206%20.9-4.35%204.24%201.03%206L12%2017.03%206.62%2019.84l1.03-6L3.3%209.6l6-.9z'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='%23000'%3E%3Cpath%20d='M12%203.2l2.7%205.5%206%20.9-4.35%204.24%201.03%206L12%2017.03%206.62%2019.84l1.03-6L3.3%209.6l6-.9z'/%3E%3C/svg%3E");
}

/* 注：`img.comments`（评论数气泡）不在这里定义 —— 本文档上方
   277~298 行的 `table.torrents img.comments` 已经用 mask 画过对话气泡了。
   那边特异性 (0,2,1) 高于此处的 (0,1,1)，重复定义只会被静默覆盖。 */

/* ══════════════════════════════════════════════════════════════
   D3. 勋章页（medal.php）—— 卡片内部结构重整（2026-09-21）
   ──────────────────────────────────────────────────────────────
   页面自带 443 行内联 <style>；2026-09-24 起它只剩几何，配色统一由本节末尾
   「勋章页配色」一段提供（原先在三个主题的 theme.css §6b，三份逐字节相同 ⇒ 上收）。

   ⚠️ 这里修的是一个**跨页误伤**：
   本文件第 1415 行那条**全局** `.detail-item` 规则，是给「详情页条目」写的
   —— 白底 + 描边 + `12px 16px` padding + `8px` margin，做成「一条条卡片」。
   但 medal.php 的 `.detail-item` 是**六宫格里的紧凑项**（label 上 / value 下），
   也被这条规则命中 ⇒ 每格凭空多出 24px padding + 8px margin，
   6 格下来卡片高出约 190px（实测卡片 329×710，其中 `.medal-details` 独占 287px）。
   这里把 medal 上下文里的 `.detail-item` 还原成紧凑形态；
   详情页不受影响 —— 选择器带了 `#outer .medal-details` 前缀，(1,2,0) 只命中勋章页。

   另外两点：
   · 卡片改 flex 纵列 + 描述 `flex:1` ⇒ 同一行里各卡片的「信息区/操作区」底边对齐，
     不会因为描述长短不一而参差；
   · 描述区内联的 `min-height:60px` 留白过大，改由 flex 撑开。
   ══════════════════════════════════════════════════════════════ */

#outer .medal-card {
    display: flex;
    flex-direction: column;
}

#outer .medal-details .detail-item {
    padding: 0;
    margin-bottom: 0;
    background: transparent;
    border: none;
    border-radius: 0;
    gap: 2px;
    align-items: flex-start;
}
#outer .medal-details .detail-item:hover {
    border: none;
    box-shadow: none;
}
/* label 走次要色、value 走主文字 —— 六格 label 全用主色会互相抢眼、层次糊掉 */
#outer .medal-details .detail-label {
    color: var(--nx-text-tertiary, var(--nx-text-secondary));
    font-weight: 600;
    letter-spacing: 0.01em;
}
#outer .medal-details .detail-value {
    color: var(--nx-text);
    font-weight: 600;
}

#outer .medal-description {
    flex: 0 0 auto;
    margin-bottom: var(--nx-space-4, 16px);
}

/* ⚠️ 2026-09-21 二稿把这里设成 `align-items: start`，因为描述区当时是 `flex:1`，
   一行的卡片会被撑出 132px 的空文本框（用户反馈「这个框太大了」）。
   2026-09-23 用户反过来反馈「内容多的时候把 div 撑大，没有对齐」⇒ 两版都只对了一半：
   问题从来不是「要不要等高」，而是**多出来的高度落在哪一格**。
   ⇒ 恢复 grid 默认的等高（删掉 align-items 即可），同时把富余量从描述区
     挪到操作区上方（下面 `margin-top:auto`）：卡片等高、按钮行底边齐平，
     而描述框始终只有内容那么高。实测 1440px 首行四张卡 553/559/625/562 → 全部 625，
     描述区仍是 60/60/126/63，没有多出一块空白。 */
#outer .medal-actions {
    margin-top: auto;
}

/* 赠送按钮：原来是 `--nx-success-text`（深绿），跟主色蓝并排很跳（用户反馈「不搭配」）。
   改成「主色柔光底 + 主色描边 + 主色文字」的次级按钮 ——
   同一张卡里 购买 = 主色实心（主操作）、赠送 = 浅主色（次操作），
   层级清楚且同色系，三主题都跟着各自主色走（Nebula 蓝 / Kawaii 粉）。
   (1,3,0) 是历史遗留：原来 theme.css §6b 有一份 (1,2,0) 的实心绿，而 theme.css
   加载在本文件之后，只能靠更高特异性压住。2026-09-24 §6b 上收进本文件后该冲突
   已不存在，但**保留 (1,3,0)** —— 它同时压得住第 10 节的 (0,1,0) 主色实心，
   且下面禁用态规则要用同样的特异性排在它之后。 */
#outer .medal-actions .medal-action-btn-unified.gift {
    background: var(--nx-primary-soft);
    color: var(--nx-primary-strong);
    border: var(--nx-border-thin) solid var(--nx-primary-border, var(--nx-border));
    box-shadow: none;
}
#outer .medal-actions .medal-action-btn-unified.gift:hover:not(:disabled) {
    background: var(--nx-primary);
    color: var(--nx-on-primary);
    border-color: var(--nx-primary);
}

/* ------------------------------------------------------------------
   勋章页配色 —— 2026-09-24 从各主题 theme.css 的 §6b 上收到共享层
   ------------------------------------------------------------------
   修的是一个**重复分层**的毛病：medal.php 自带 443 行内联 <style>，配色全是
   硬编码（蓝渐变 #007cba→#00a5ff、浅底 #f5f7fa→#e4edf5、纯白、#333/#666）；
   三个主题的 theme.css 又各写一份 §6b，用 `#outer` 前缀把这些颜色整页压回去。
   而**三份 §6b 逐字节相同** —— 既然没有任何主题差异，它本就不该待在 per-theme 层。
   ⇒ 现在 medal.php 的内联只剩几何（尺寸/圆角/间距/过渡/媒体查询），
     颜色由本节一处提供；§6b 从三个 theme.css 删除。

   `#outer` 前缀照旧保留：medal.php 的内联 <style> 仍在 <body> 内、晚于本文件加载，
   将来谁往那儿补一句颜色，(1,x,0) 依旧压得住，不必动用 !important。

   上收时顺手删掉的三条**死规则**（迁移前 CDP 实测，均匹配不到任何元素）：
   · `.buy-btn` / `.gift-btn` 全族 —— markup 只吐 `.medal-action-btn-unified.buy|gift`，
     老类名改版后不再产出，medal.php 里对应的几段一并删。
   · `#outer .detail-label { --nx-primary-strong }` —— 被本文件上面那条
     `#outer .medal-details .detail-label`（(1,2,0)）压住，实际生效的一直是 text-tertiary。
   · `#outer .medal-action-btn-unified.gift` 的实心绿 —— 被 (1,3,0) 的主色柔光盖掉，
     自 9-23「绿色跟主色蓝很跳」那次反馈之后就没再生效过。
   ------------------------------------------------------------------ */

/* 顶部筛选区 */
#outer .medal-search-input {
    background: var(--nx-surface);
    color: var(--nx-text);
    border-color: var(--nx-border-strong);
    box-shadow: var(--nx-shadow-sm);
}
#outer .medal-search-input::placeholder { color: var(--nx-text-tertiary); }
#outer .medal-search-input:focus {
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
#outer .medal-search-btn {
    background: var(--nx-primary);
    color: var(--nx-on-primary);
}
#outer .medal-search-btn:hover {
    background: var(--nx-primary-hover);
    box-shadow: var(--nx-shadow-md);
}
#outer .medal-reset-btn {
    background: var(--nx-surface-alt);
    color: var(--nx-text-secondary);
}
#outer .medal-reset-btn:hover {
    background: var(--nx-surface-hover);
    color: var(--nx-text);
    box-shadow: var(--nx-shadow-md);
}

/* 卡片本体 —— 头部的蓝色渐变条一律去掉，走「凹面 + 主色描边」 */
#outer .medal-card {
    background: var(--nx-surface);
    border-color: var(--nx-border);
    box-shadow: var(--nx-shadow-sm);
}
#outer .medal-card:hover {
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-lg);
}
#outer .medal-header {
    background: var(--nx-surface-sunken);
    box-shadow: none;
}
#outer .medal-name {
    color: var(--nx-text);
    text-shadow: none;
}
#outer .medal-description { color: var(--nx-text-secondary); }
#outer .medal-actions { border-top-color: var(--nx-border); }
#outer .gift-fee { color: var(--nx-text-secondary); }
#outer .no-medals { color: var(--nx-text-tertiary); }

/* 勋章圆牌：容器浮起一档、图片本身只留最薄的一层，避免双重投影显得发虚。
   悬停放大 2.5 倍时的光晕原烧死成 #007cba（站内蓝），在 Kawaii 粉主题下是一圈
   外来蓝 —— 改成跟着主色走。 */
#outer .medal-image-container {
    background: var(--nx-surface-alt);
    box-shadow: var(--nx-shadow-sm);
}
#outer .medal-image { box-shadow: var(--nx-shadow-xs); }
#outer .medal-image:hover {
    box-shadow: 0 0 20px color-mix(in srgb, var(--nx-primary) 45%, transparent);
}

/* 图片点击放大的全屏遮罩。两条**故意不令牌化**：
   遮罩恒为黑色、预览图的光晕恒为白色 —— 深色底上白晕才看得见，
   换成 --nx-text 在浅色主题就成了黑圈贴黑布，等于没有。 */
#outer .medal-image-overlay { background: rgba(0, 0, 0, 0.75); }
#outer .medal-image-overlay img { box-shadow: 0 0 30px rgba(255, 255, 255, 0.2); }

/* 操作按钮 —— 购买 = 主色实心，赠送见上面的 (1,3,0) 主色柔光。
   ⚠️ 这里**不能**省下来交给第 10 节的 `.medal-action-btn-unified`（(0,1,0)）：
   这些按钮是 `<input type="button">`，各主题 theme.css 有一条通用
   `input[type="button"]`（(0,1,1)）在**后面**且特异性更高，会把它们刷成
   通用次级按钮底（`--nx-btn-bg`）。原先压住它的是 theme.css §6b 的
   `#outer .medal-action-btn-unified.buy`（(1,2,0)）—— §6b 上收时这条必须一起搬过来，
   少了它「购买」按钮当场失去主色（本次迁移实测踩到，靠计算样式对比 diff 抓到）。 */
#outer .medal-actions .medal-action-btn-unified.buy {
    background: var(--nx-primary);
    color: var(--nx-on-primary);
}
/* 禁用态排在 gift 规则之后且同为 (1,3,0) ⇒ 同样压得住赠送的柔光底 */
#outer .medal-actions .medal-action-btn-unified:disabled {
    background: var(--nx-surface-sunken);
    color: var(--nx-text-tertiary);
    border-color: var(--nx-border);
    box-shadow: none;
}

/* 赠予对象 UID 输入框 */
#outer .uid-input {
    background: var(--nx-surface);
    color: var(--nx-text);
    border-color: var(--nx-border-strong);
}
#outer .uid-input:focus {
    border-color: var(--nx-primary);
    box-shadow: var(--nx-shadow-focus);
}
/* 禁用态：这张卡片不可赠送时 UID 框是 disabled 的，但它原先和可用态长得一模一样。
   全站那条 `button:disabled, input[type="submit"]:disabled, input[type="button"]:disabled,
   .nx-btn:disabled { opacity:.55 }` 兜底（本文件按钮一节末尾）没有 type=number，
   所以这里拿不到 —— 照 .nx-input:disabled 那套补齐：沉底灰 + 禁用字色 + not-allowed。 */
#outer .uid-input:disabled {
    background: var(--nx-surface-sunken);
    color: var(--nx-text-disabled);
    border-color: var(--nx-border);
    cursor: not-allowed;
    box-shadow: none;
}
#outer .uid-input:disabled::placeholder {
    color: var(--nx-text-disabled);
}

/* ══════════════════════════════════════════════════════════════
   D2. 排行榜前三名徽章（topten.php）
   ──────────────────────────────────────────────────────────────
   服务端数据行是 `<tr><td class="rowfollow">序号</td>…`，名次列没有任何
   钩子，纯 CSS 只能靠 nth-child 猜行号（榜单表头行数一变就错位）。
   所以由 JS（nexus.js → nxRankMedals）读首列文本，命中 1/2/3 才给
   <tr> 打上 .nx-rank-1/2/3；这里只负责视觉。

   两个刻意的做法：
   ① 原数字用 `color: transparent` 隐去，而不是 `font-size: 0` ——
      保留它的宽高占位，td 尺寸与其它数据行完全一致。否则会出现
      「只有前三行比别的行高」这种一眼就看出来的毛病。
   ② 徽章绝对定位居中压在原数字上，同样不参与撑高。
   ══════════════════════════════════════════════════════════════ */
tr.nx-rank-1 > td:first-child,
tr.nx-rank-2 > td:first-child,
tr.nx-rank-3 > td:first-child {
    position: relative;
    color: transparent;   /* 隐去原数字，徽章内用 content 重绘同一个数字 */
    text-shadow: none;
}

tr.nx-rank-1 > td:first-child::before,
tr.nx-rank-2 > td:first-child::before,
tr.nx-rank-3 > td:first-child::before {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 26px;
    height: 26px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-size: var(--nx-font-sm, 12px);
    font-weight: var(--nx-weight-bold, 700);
    line-height: 1;
    color: #fff;
    text-shadow: 0 1px 1px rgba(15, 23, 42, 0.32);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.62),
        inset 0 -1px 0 rgba(15, 23, 42, 0.16),
        0 2px 5px rgba(15, 23, 42, 0.22);
}

/* 金 */
tr.nx-rank-1 > td:first-child { box-shadow: inset 3px 0 0 0 #f59e0b; }
tr.nx-rank-1 > td:first-child::before {
    content: "1";
    background-image: linear-gradient(160deg, #fde68a 0%, #f59e0b 55%, #d97706 100%);
}

/* 银 */
tr.nx-rank-2 > td:first-child { box-shadow: inset 3px 0 0 0 #94a3b8; }
tr.nx-rank-2 > td:first-child::before {
    content: "2";
    background-image: linear-gradient(160deg, #ffffff 0%, #cbd5e1 55%, #94a3b8 100%);
    color: #475569;
    text-shadow: none;
}

/* 铜 */
tr.nx-rank-3 > td:first-child { box-shadow: inset 3px 0 0 0 #c2743c; }
tr.nx-rank-3 > td:first-child::before {
    content: "3";
    background-image: linear-gradient(160deg, #fdba74 0%, #ea580c 55%, #9a3412 100%);
}


/* ── 日志导航的五个图标（log.php 的 logmenu()）────────────────────────────
   ⚠️ 这里**不能**像 usercp 那样用 nth-child 分配图标：logmenu() 里的「趣味盒」（funbox）
      是条件渲染的（`$showfunbox_main == 'yes'`），条目数会变 ⇒ nth-child 会串位。
      改用 [href*="action=xxx"] 直接绑定语义（`*=` 而非 `^=` —— NexusPHP 的链接
      大量是绝对 URL，前缀匹配会漏）。 */
/* 常规日志 —— 文档 */
#lognav ul#logmenu > li > a[href*="action=dailylog"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/><polyline points='14 2 14 8 20 8'/><line x1='8.5' y1='13' x2='15.5' y2='13'/><line x1='8.5' y1='17' x2='13' y2='17'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z'/><polyline points='14 2 14 8 20 8'/><line x1='8.5' y1='13' x2='15.5' y2='13'/><line x1='8.5' y1='17' x2='13' y2='17'/></svg>");
}
/* 史册 —— 书 */
#lognav ul#logmenu > li > a[href*="action=chronicle"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 19.5A2.5 2.5 0 0 1 6.5 17H20'/><path d='M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 19.5A2.5 2.5 0 0 1 6.5 17H20'/><path d='M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z'/></svg>");
}
/* 趣味盒（funbox）—— 立方体盒子 */
#lognav ul#logmenu > li > a[href*="action=funbox"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'/><polyline points='3.3 7 12 12 20.7 7'/><line x1='12' y1='22' x2='12' y2='12'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z'/><polyline points='3.3 7 12 12 20.7 7'/><line x1='12' y1='22' x2='12' y2='12'/></svg>");
}
/* 首页公告 —— 铃铛（通知） */
#lognav ul#logmenu > li > a[href*="action=news"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9'/><path d='M13.7 21a2 2 0 0 1-3.4 0'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9'/><path d='M13.7 21a2 2 0 0 1-3.4 0'/></svg>");
}
/* 投票 —— 柱状图 */
#lognav ul#logmenu > li > a[href*="action=poll"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 20h16'/><line x1='8' y1='20' x2='8' y2='13'/><line x1='13' y1='20' x2='13' y2='9'/><line x1='18' y1='20' x2='18' y2='15'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M4 20h16'/><line x1='8' y1='20' x2='8' y2='13'/><line x1='13' y1='20' x2='13' y2='9'/><line x1='18' y1='20' x2='18' y2='15'/></svg>");
}

/* ── 私信邮箱导航的图标（messages.php 的 messagemenu()）───────────────────
   条目顺序固定的是前两个（收件箱、发件箱），其后是用户自建的 pmboxes，
   名称与条数都由数据决定 ⇒ 只对前两项按位置分配，其余统一用文件夹兜底。
   默认规则特异性最低（2 id + 元素），nth-child / [href] 各多一项 ⇒ 都能盖住它。 */
/* 自建邮箱（默认）—— 文件夹 */
#pmboxnav ul#pmboxmenu > li > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 7.5A2 2 0 0 1 5 5.5h3.7l2 2H19a2 2 0 0 1 2 2v7.8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><path d='M3 7.5A2 2 0 0 1 5 5.5h3.7l2 2H19a2 2 0 0 1 2 2v7.8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'/></svg>");
}
/* 收件箱 —— 收件盘 */
#pmboxnav ul#pmboxmenu > li:nth-child(1) > a::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='22 12 16 12 14 15 10 15 8 12 2 12'/><path d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='22 12 16 12 14 15 10 15 8 12 2 12'/><path d='M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z'/></svg>");
}
/* 发件箱 —— 纸飞机（`box=-1` 是它的固定 location） */
#pmboxnav ul#pmboxmenu > li > a[href*="box=-1"]::before {
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><line x1='22' y1='2' x2='11' y2='13'/><polygon points='22 2 15 22 11 13 2 9 22 2'/></svg>");
            mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><line x1='22' y1='2' x2='11' y2='13'/><polygon points='22 2 15 22 11 13 2 9 22 2'/></svg>");
}
/* ==========================================================================
   2026-09-21 · 任务列表（task.php）
   --------------------------------------------------------------------------
   标记见 public/task.php。表格本体已经是 .nx-table，圆角卡片 / 斑马纹 / 吸顶
   表头 / 行 hover 全都白拿了，这一段只解决「十列怎么排」。
   改前的毛病（实测 1400px 视口）：
     ① 「目标用户」一格铺 15 个等级名，既是全表最宽、又是字号最大的一格，
        把左右全挤了 —— 名称断成「发种任/务-简单」三行，描述断成四行；
     ② 开始/结束各是一整串 `2026-09-21 00:47:10`，两列并排纯噪音；
     ③ 奖励 / 扣除 / 名额是重要信息，却和次要信息同一个字号同一个颜色。
   思路：短列一律锁死不换行，只留「目标用户」「描述」允许折行并各给上限，
   整表给 min-width、窄屏交给外层 .nx-task-scroll 横向滚 —— 压扁列不如滚。
   ========================================================================== */

/* 横向滚动容器。表格的圆角由 .nx-table 自己画，这里只负责溢出。 */
.nx-task-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    /* 滚动条贴着卡片底边会盖住圆角，留一道缝 */
    padding-bottom: var(--nx-space-1);
}
table.nx-task-table { min-width: 1080px; margin-bottom: 0; }

/* 光给 .nx-task-scroll 加 overflow-x 是不够的：它的祖先 <table class="main"> 是
   自动布局，min-content 被 1080px 的表格顶到 1114px，于是整张表【顶破】480px 的
   td#outer，滚的是整个页面而不是这个容器（实测 docSW=1122 / clientW=480）。
   把承载页改成固定布局，td.embedded 才真的收到 430px，容器内部滚起来。
   只在任务页命中；桌面端实测宽度不变（1334/1334），900px 以下由溢出页面转为容器滚动。 */
table.main:has(.nx-task-scroll) { table-layout: fixed; }

/* .nx-table 的默认单元格内距是 space-4（16px）四边 —— 十列表格光左右内距就
   吃掉 10×32 = 320px，占 1200px 卡片的四分之一，剩下的才轮到内容分。
   收到 12px 省出近 160px，全部还给「描述」这一列，实测它从折四行变两行。 */
.nx-task-table > thead > tr > th,
.nx-task-table > tbody > tr > td { padding-left: var(--nx-space-3); padding-right: var(--nx-space-3); }

/* ---- 首页三处「还在吃 HTML 属性」的表格（2026-09-22）----
   它们用 cellpadding 定内边距：top-uploader ×2 是 5px、last-five-torrents 实际渲染成
   12px 4px 12px 8px（左右不对称）、站点数据那块是 10px；而卡片体系的表格统一是 12px/16px。
   HTML 属性属于「表现提示」，特异性低于任何作者 CSS → 这里直接覆盖即可，不必改标记。
   ⚠️ 老主题（2/3/4/6/7/8）加载不到本文件，那边仍是原来的属性值。 */
table.top-uploader > tbody > tr > td,
table.last-five-torrents > tbody > tr > td,
table.main[width="60%"] > tbody > tr > td {
    padding: var(--nx-space-3) var(--nx-space-4);
}

/* ── 短列不换行 ────────────────────────────────────────────────────────
   名称以前挂的是通用 .nowrap，但那条规则在别处被表格自动布局的压缩打败了；
   这里用组件自己的类，权重稳。 */
.nx-task-table .nx-task-name,
.nx-task-table .nx-task-time,
.nx-task-table .nx-task-num,
.nx-task-table .nx-task-quota,
.nx-task-table .nx-task-action,
.nx-task-table .nx-task-col-num,
.nx-task-table .nx-task-col-action { white-space: nowrap; }

.nx-task-table .nx-task-name strong { color: var(--nx-text); font-weight: var(--nx-weight-semibold); }

/* ── 时间：日期一行、时分一行（秒在 PHP 里已经去掉了） ───────────────── */
.nx-task-table .nx-task-date,
.nx-task-table .nx-task-clock { display: block; line-height: var(--nx-leading-tight); font-variant-numeric: tabular-nums; }
.nx-task-table .nx-task-date  { color: var(--nx-text-secondary); }
.nx-task-table .nx-task-clock { font-size: var(--nx-font-xs); color: var(--nx-text-tertiary); }

/* ── 数值列：右对齐 + 等宽数字，赚/赔分色 ───────────────────────────── */
.nx-task-table .nx-task-col-num { text-align: right; }
.nx-task-table .nx-task-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
    font-weight: var(--nx-weight-semibold);
}
.nx-task-table .nx-task-num--gain { color: var(--nx-primary-strong); }
.nx-task-table .nx-task-num--cost { color: var(--nx-danger-text); font-weight: var(--nx-weight-medium); }

/* ── 目标用户：徽章化，超 5 个折成 +N（完整名单在 title 上） ─────────── */
.nx-task-filters {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nx-space-1);
    max-width: 216px;
}
.nx-task-filters .nx-badge {
    padding: 1px var(--nx-space-2);
    font-size: var(--nx-font-xs);
    line-height: 1.7;
    font-weight: var(--nx-weight-normal);
}
/* 折叠：默认只露前 5 个，其余靠 .is-open 显隐（节点一直在，不重渲染）。
   display 值必须和 .nx-badge 一致（inline-flex），否则展开后排版会跳。 */
.nx-task-filters .is-fold { display: none; }
.nx-task-filters.is-open .is-fold { display: inline-flex; }

/* +N / −N 开关。长得跟徽章一样，但它是可点的。
   ⚠ 选择器必须带上两级类名：上面那条全局按钮规则
     `button:not([class*="xdsoft"]):not([class*="nx-ts-"])` 是 (0,2,1) —— 两个 :not()
     各按属性选择器计 (0,1,0)。只写 button.nx-task-fold 是 (0,1,1)，会被它整个吃掉
     （实测内距停在 space-3/space-5、圆角停在 radius-md）。这里 (0,3,1) 才稳。 */
.nx-task-table .nx-task-filters button.nx-task-fold {
    display: inline-flex;
    align-items: center;
    padding: 1px var(--nx-space-2);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-full);
    background: var(--nx-surface-sunken);
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-xs);
    line-height: 1.7;
    white-space: nowrap;
    cursor: pointer;
    transition: color var(--nx-dur-fast) ease, border-color var(--nx-dur-fast) ease;
}
.nx-task-table .nx-task-filters button.nx-task-fold:hover {
    border-color: var(--nx-primary-border);
    background: var(--nx-primary-soft);
    color: var(--nx-primary-strong);
}
.nx-task-table .nx-task-filters button.nx-task-fold:focus-visible { outline: var(--nx-border-thin) solid var(--nx-primary); outline-offset: 2px; }
.nx-task-filter-more {
    display: block;
    flex-basis: 100%;
    font-size: var(--nx-font-xs);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text-tertiary);
}

/* ── 名额：数字下面挂一条占用度，0/100 和 98/100 一眼能分出来 ───────── */
.nx-task-table .nx-task-quota { text-align: right; }
.nx-task-quota__bar {
    display: block;
    height: 3px;
    margin-top: var(--nx-space-1);
    border-radius: var(--nx-radius-full);
    background: var(--nx-surface-sunken);
    overflow: hidden;
}
.nx-task-quota__bar > i {
    display: block;
    height: 100%;
    /* 进度值由 <i> 的行内 --nx-task-fill 给出；这里只是行内样式缺席时的兜底 */
    --nx-task-fill: 0%;
    width: var(--nx-task-fill);
    border-radius: inherit;
    background: var(--nx-primary);
}
.nx-task-quota.is-full .nx-task-quota__bar > i { background: var(--nx-danger); }

/* ── 描述：原文里有裸换行，pre-line 让它成为正常的两行，而不是塌成一行 ─
   ⚠ 这里不能用 max-width：自动布局下它是「上限」，只把列往窄里推、不会
     替它争到空间（实测被挤到 150px 折成四行）。改成 width 才真的分到一份。 */
.nx-task-table .nx-task-desc {
    width: 20%;
    min-width: 200px;
    white-space: pre-line;
    font-size: var(--nx-font-sm);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text-secondary);
}

/* ── 操作列 ─────────────────────────────────────────────────────────── */
.nx-task-table .nx-task-col-action,
.nx-task-table .nx-task-action { text-align: center; }
.nx-task-table .nx-task-action input[type="button"] {
    min-width: 78px;
    padding: var(--nx-space-2) var(--nx-space-4);
    font-size: var(--nx-font-sm);
    justify-content: center;
}

/* 窄屏：让「描述」跟着表格一起横向滚，而不是被压成竖排 */
@media (max-width: 768px) {
    .nx-task-filters { max-width: none; }
}

/* ==========================================================================
   2026-09-27 · 魔力红包（redpacket.php）
   --------------------------------------------------------------------------
   标记见 public/redpacket.php。这一页能复用的都复用了全局组件
   （.nx-alert / .nx-badge / .nx-btn / .nx-input / .nx-select / .nx-textarea /
    .nx-table / td.rowhead + td.rowfollow），所以本段只剩全局没有对应物的几件：
   页面级标签条、红包码分享框、六列表格的列排布、表单里控件的限宽。
   ========================================================================== */

/* ── 标签条（首页 / 我的红包 / 领取记录）──────────────────────────────
   全站此前没有「页面内」的标签条：ul.menu 只被 nav#nav 样式化，拿过来会是
   一条顶部导航的样子。配色仍全部走令牌，不引入新颜色。
   ⚠️ 整段带 #outer：本节在 components.css:1536 那条 `#outer ul { list-style: disc }`
      之后、但它是 ID 级 (1,0,1) —— 不带 #outer 的类选择器 (0,1,0) 压不住，
      实测胶囊条左边会多出一颗圆点、左内距回到 24px。 */
#outer ul.nx-rp-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--nx-space-1);
    margin: 0 0 var(--nx-space-4);
    padding: var(--nx-space-1);
    list-style: none;
    background: var(--nx-surface-sunken);
    border: var(--nx-border-thin) solid var(--nx-border);
    border-radius: var(--nx-radius-full);
}
#outer .nx-rp-tabs > li { flex: 0 0 auto; margin: 0; }
#outer .nx-rp-tabs > li > a {
    display: inline-flex;
    padding: var(--nx-space-2) var(--nx-space-5);
    border-radius: var(--nx-radius-full);
    color: var(--nx-text-secondary);
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-medium);
    line-height: var(--nx-leading-snug);
    text-decoration: none;
    transition: color var(--nx-dur-fast) var(--nx-ease-out),
                background-color var(--nx-dur-fast) var(--nx-ease-out);
}
#outer .nx-rp-tabs > li > a:hover { color: var(--nx-text); background: var(--nx-surface-hover); }
#outer .nx-rp-tabs > li.selected > a {
    background: var(--nx-surface);
    color: var(--nx-primary-strong);
    font-weight: var(--nx-weight-semibold);
    box-shadow: var(--nx-shadow-xs);
}

/* ── 红包码 / 分享链接 ───────────────────────────────────────────────
   码是给人抄的，等宽 + 字距；链接是给人转的，要能看全长，所以两者分开。 */
.nx-rp-code-input {
    font-family: var(--nx-font-mono);
    letter-spacing: 0.08em;
    text-align: center;
}
.nx-rp-share {
    display: flex;
    flex-direction: column;
    gap: var(--nx-space-3);
    margin-bottom: var(--nx-space-2);
}
/* 一格一行（码 / 链接），各自带一颗复制键。并排的话最长最需要看清的链接框只剩半行。 */
.nx-rp-share-row {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
    gap: var(--nx-space-2);
}
/* .nx-input 自带 width:100%，在 flex 行里会把按钮顶出去 —— 交回 flex-basis。 */
.nx-rp-share .nx-input { width: auto; min-width: 0; }
.nx-rp-share .nx-rp-code-input { flex: 0 1 168px; }
.nx-rp-share .nx-rp-link-input { flex: 1 1 260px; font-size: var(--nx-font-sm); }
/* 复制键默认不画，redpacket.js 给容器加上 .js 才露出来：无 JS 时不留一颗点了没反应
   的死键，两个框本身 onfocus 全选，长按/拖选照样复制。
   按钮不写死高度，靠 .nx-rp-share-row 的 align-items:stretch 长到和输入框同高。 */
.nx-rp-copy { display: none; }
.nx-rp-share.js .nx-rp-copy { display: inline-flex; flex: 0 0 auto; }
.nx-rp-copy.is-done { color: var(--nx-primary); border-color: var(--nx-primary); }
/* 复制失败要说得更重一点：用户下一步动作（长按选中）取决于看见这句话 */
.nx-rp-copy.is-fail { color: var(--nx-danger); border-color: var(--nx-danger); }

.nx-rp-claim {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--nx-space-3);
}
.nx-rp-claim .nx-rp-code-input { width: auto; flex: 0 1 200px; }

/* 带码直达：.nx-rp-open 那套标记外面套了一层 form（点「开」= 提交 do_claim）。
   form 本身只负责和下面的手动领取框留出间距，卡片外观仍由 .nx-rp-open 给。 */
.nx-rp-seal { margin: 0 0 var(--nx-space-4); }

/* ── 次要说明文字：贴在控件下方，不抢主体的视觉重量 ───────────────── */
.nx-rp-hint {
    margin: var(--nx-space-2) 0 0;
    font-size: var(--nx-font-sm);
    line-height: var(--nx-leading-snug);
    color: var(--nx-text-secondary);
}
.nx-rp-hint b { color: var(--nx-text); font-weight: var(--nx-weight-semibold); }
/* 三种红包类型的说明是连排的三段，段距收到 4px，读起来是一条图例而非三条提示 */
.nx-rp-hint + .nx-rp-hint { margin-top: var(--nx-space-1); }
.nx-rp-muted { font-size: var(--nx-font-xs); color: var(--nx-text-tertiary); }
/* 时间戳不许在日期与时分秒之间断行：带秒之后 19 个字符，窄屏一断就是两行 */
.nx-rp-time { white-space: nowrap; }

/* 选「专属」后 redpacket.js 给接收人那行加 is-need：此刻它才真的必填，
   标签和描边一起亮，别等提交被服务端打回来才知道。
   特异度要压过 table.nx-rp-form td.rowhead (0,2,2)，所以带上 tr.is-need。 */
table.nx-rp-form tr.is-need > td.rowhead { color: var(--nx-primary); }
#outer table.nx-rp-form tr.is-need td.rowfollow .nx-input { border-color: var(--nx-primary); }

/* ── 列表 ────────────────────────────────────────────────────────────
   和任务表同样的道理：祖先 <table class="main"> 是自动布局，min-content 会被
   表格自己的 min-width 顶开，届时滚的是整页而不是这个容器。给它固定布局，
   容器才真的接管横向滚动。 */
.nx-rp-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: var(--nx-space-1);
}
table.main:has(.nx-rp-scroll) { table-layout: fixed; }
table.nx-rp-table { min-width: 620px; margin-bottom: 0; }
/* 「最近发出」那块只有三列，不需要撑到 620px —— 同特异性，靠源顺序压过上一条 */
table.nx-rp-table-compact { min-width: 0; }
.nx-rp-table > thead > tr > th,
.nx-rp-table > tbody > tr > td { padding-left: var(--nx-space-3); padding-right: var(--nx-space-3); }

/* 金额列：右对齐 + 等宽数字，「1000.0 / 20 份」这种两行数据才对得齐 */
.nx-rp-table .nx-rp-col-num,
.nx-rp-table .nx-rp-num { text-align: right; }
.nx-rp-table .nx-rp-num {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    font-weight: var(--nx-weight-semibold);
}
/* 留言列：PHP 已按 40 字截断，这里只是不让它被挤成一列竖排 */
.nx-rp-table .nx-rp-cell-msg {
    min-width: 140px;
    max-width: 260px;
    color: var(--nx-text-secondary);
}
.nx-rp-table .nx-rp-empty {
    padding: var(--nx-space-6) var(--nx-space-4);
    text-align: center;
    color: var(--nx-text-tertiary);
}
.nx-rp-table code { color: var(--nx-text); font-weight: var(--nx-weight-medium); }
/* 「手气最佳」跟着徽章走，只把尺寸降到和表格里的小字同级（同 task 过滤徽章的处理） */
.nx-rp-table .nx-rp-best {
    padding: 0 var(--nx-space-2);
    font-size: var(--nx-font-xs);
    line-height: 1.7;
    font-weight: var(--nx-weight-normal);
}

/* ── 详情页信息表 + 创建表单：两张「标签 / 值」两列表 ───────────────── */
/* 管理页列表里的「作废」按钮：基础按钮的 padding 会把所在行撑到 40px 高，
   一屏 20 行就是 800px 的空白。选择器要写两级类（button.nx-btn.nx-rp-btn-sm = (0,2,1)）
   才压得住同特异度的全局 button:not(...):not(...) 基础规则 —— 和 .nx-btn-primary 那支同理。 */
button.nx-btn.nx-rp-btn-sm {
    padding: 0 var(--nx-space-2);
    font-size: var(--nx-font-xs);
    line-height: 1.8;
    gap: 0;
}


/* 明细表在 .nx-rp-scroll 里（自己不带下外边距），信息表紧贴着它，间距从这里给 */
table.nx-rp-meta { margin: var(--nx-space-4) 0 var(--nx-space-4); }
table.nx-rp-meta td.rowhead,
table.nx-rp-form td.rowhead {
    width: 150px;
    white-space: nowrap;
    vertical-align: top;
}
table.nx-rp-meta td.rowfollow { vertical-align: top; }

/* 创建表每行是「标签 + 控件」，不是数据行：.nx-table 的斑马纹和悬停要关掉，
   否则输入框所在行会随鼠标变亮，看着像整行可点。
   斑马纹用的是 background-image，清掉它不影响 td.rowhead 自己的底色；
   悬停用的是 background 简写，会连 td.rowhead 一起刷掉，所以补回原色。
   两条都是 (0,2,4)，和上面的 .nx-table 规则同权重，靠源顺序取胜。 */
table.nx-rp-form > tbody > tr:nth-child(even) > td { background-image: none; }
table.nx-rp-form > tbody > tr:hover > td { background: transparent; }
table.nx-rp-form > tbody > tr:hover > td.rowhead { background: var(--nx-surface-sunken); }

/* 控件默认 width:100%，在整格宽的表单里会拉成一条横幅。
   金额 / 份数 / 时长按内容给宽；留言和收件人确实要写长，保持铺满。
   ⚠️ 必须带 #outer 和 td：theme.css:190 那条给管理页设的
      `#outer form table td select { max-width: 100% }` 是 (1,1,3)，而且它排在
      本文件之后 —— 只写 `table.nx-rp-form select` (0,1,3) 会被它整个吃掉
      （实测下拉框铺满 1132px，而同表的数字框却按 140px 收住了：那条只列了
       text / password / select / textarea，没管 number）。 */
#outer table.nx-rp-form td.rowfollow input[type="number"] { max-width: 140px; }
#outer table.nx-rp-form td.rowfollow select { max-width: 200px; }

/* 管理页的筛选条：一行一个条件，文本框拉满整行会把四行冲成四张表，
   所以收到和上面两个下拉同宽，让控件左边缘连成一条竖线。
   前台创建表没有 .nx-rp-filter —— 那里的留言和收件人确实要写长。 */
#outer table.nx-rp-form.nx-rp-filter td.rowfollow input[type="text"] { width: 200px; max-width: 100%; }

/* 详情页的操作按钮：领取 / 作废两个表单并排。
   上方间距已经由 .nx-rp-meta 的 margin-bottom 给过，这里不再叠加。 */
.nx-rp-inline {
    display: inline-flex;
    margin: 0 var(--nx-space-2) 0 0;
}
/* 详情页读完明细/元信息，末尾给一条明确的退路（tab 栏在顶部，够不着时要滚回去） */
.nx-rp-back { margin: var(--nx-space-4) 0 0; }

@media (max-width: 768px) {
    .nx-rp-tabs { border-radius: var(--nx-radius-lg); }
    table.nx-rp-meta td.rowhead,
    table.nx-rp-form td.rowhead { width: 110px; }
    /* 窄屏仍是一格一行，只把框的基准宽度收下来给按钮留位（按钮不许被挤到第二行） */
    .nx-rp-share .nx-rp-code-input { flex: 1 1 120px; }
    .nx-rp-share .nx-rp-link-input { flex: 1 1 160px; }
}

/* ==========================================================================
   2026-09-27 · 魔力红包 · 拆封动效
   --------------------------------------------------------------------------
   标记见 public/redpacket.php 的 do_claim 分支，脚本是 public/js/redpacket.js。
   微信那只红包的意思：结果页先给一张没拆开的封皮，点「开」才抖一下、封口飞起、
   金额从 0.0 滚到实得。三条硬约束：
   1. 金额是服务端渲染进 .nx-rp-open-num 的，JS 只在确认要播动画时才清零。
      所以无 JS / JS 挂了 / .no-fx（本会话拆过、或系统要求减少动效）都是直接看到钱，
      绝不会出现「拆不开」或「金额凭空冒出来」。
   2. 正反面共用一个 grid 槽位（都落在 1/1），卡片高度由较高的那面决定，
      翻面时不抖版。⚠️ 副作用：只渲染封皮那一面时，back 仍撑高 —— 所以 back
      用 opacity 隐藏而不是 display:none，本来就要参与布局。
   3. 封皮/烫金是这只红包自己的语义色，不跟主题的红走（Nebula 的 --nx-danger 在
      暗色下是 #f85149、亮色下 #b91c1c，两套都不像红包），故本段自带局部变量。
   ========================================================================== */

.nx-rp-open-wrap { margin-bottom: var(--nx-space-6); }

.nx-rp-open {
    --nx-rp-cover:      #e0603a;
    --nx-rp-cover-deep: #b93020;
    --nx-rp-gold:       #f2c877;
    --nx-rp-gold-deep:  #c8963c;
    --nx-rp-ink:        #fff6e6;

    display: flex;
    justify-content: center;
    padding: var(--nx-space-2) 0 var(--nx-space-3);
}

.nx-rp-open-card {
    position: relative;
    display: grid;
    width: min(320px, 86vw);
    padding: var(--nx-space-7) var(--nx-space-6);
    border-radius: var(--nx-radius-lg);
    background: linear-gradient(165deg, var(--nx-rp-cover) 0%, var(--nx-rp-cover-deep) 100%);
    box-shadow: var(--nx-shadow-lg);
    text-align: center;
    /* 封口是 rotateX 的，需要透视；overflow 不能设 hidden，否则飞起的封口被切 */
    perspective: 900px;
}

.nx-rp-open-card::before {
    content: '';
    position: absolute;
    inset: 0;
    border: 1px solid rgba(242, 200, 119, .32);
    border-radius: inherit;
    pointer-events: none;
}

.nx-rp-open-front,
.nx-rp-open-back {
    grid-area: 1 / 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    /* 卡片高度由内容多的那面（封皮）决定，背板只有三行 —— 不居中的话
       金额会顶在卡片上沿、下面空一大片（实测截图就是这样）。 */
    justify-content: center;
    gap: var(--nx-space-3);
}

/* ── 封皮正面 ─────────────────────────────────────────────────────────── */
.nx-rp-open-front { position: relative; z-index: 3; }

.nx-rp-open-from,
.nx-rp-open-msg { margin: 0; }

.nx-rp-open-from {
    font-size: var(--nx-font-sm);
    color: rgba(255, 246, 230, .8);
}

.nx-rp-open-msg {
    font-size: var(--nx-font-lg);
    font-weight: var(--nx-weight-semibold);
    line-height: var(--nx-leading-snug);
    color: var(--nx-rp-ink);
}

.nx-rp-open-tap {
    margin: 0;
    font-size: var(--nx-font-sm);
    color: rgba(255, 246, 230, .72);
}

/* 带元素名：base.css:64 那条裸 button 只给了 font/color 的 inherit，
   这里必须自己把金色底和字色盖回来 */
button.nx-rp-open-btn {
    display: grid;
    place-items: center;
    width: 76px;
    height: 76px;
    margin: var(--nx-space-2) 0;
    padding: 0;
    border: 2px solid rgba(255, 246, 230, .72);
    border-radius: 50%;
    background: radial-gradient(circle at 34% 28%, #ffedc2, var(--nx-rp-gold) 58%, var(--nx-rp-gold-deep));
    box-shadow: var(--nx-shadow-md);
    cursor: pointer;
}

button.nx-rp-open-btn > b {
    font-size: var(--nx-font-3xl);
    font-weight: var(--nx-weight-bold);
    line-height: 1;
    color: #8c2a12;
}

button.nx-rp-open-btn:hover { transform: translateY(-1px) scale(1.04); }
button.nx-rp-open-btn:active { transform: scale(.95); }

/* 只有真的会播动画时才有 JS：没 JS 时不该有个跳来跳去却点不动的按钮 */
.nx-rp-open.js .nx-rp-open-btn { animation: nx-rp-open-pulse 1.8s ease-in-out infinite; }

/* ── 结果背板 ─────────────────────────────────────────────────────────── */
.nx-rp-open-back { position: relative; z-index: 1; }

/* JS 接管且还没拆：背板藏着等封皮让开，但仍在布局里撑住卡片高度 */
.nx-rp-open.js:not(.is-open) .nx-rp-open-back {
    opacity: 0;
    transform: translateY(10px) scale(.95);
    pointer-events: none;
}

.nx-rp-open.js .nx-rp-open-back {
    transition: opacity .38s ease .06s, transform .45s cubic-bezier(.2, .9, .25, 1.35) .06s;
}

.nx-rp-open.js.is-open .nx-rp-open-back {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

.nx-rp-open.js:not(.is-open) .nx-rp-open-front {
    opacity: 1;
    transition: opacity .3s ease, transform .4s ease;
}

.nx-rp-open.js.is-open .nx-rp-open-front {
    opacity: 0;
    transform: translateY(-8px) scale(.97);
    pointer-events: none;
}

.nx-rp-open-amount {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: var(--nx-space-2);
    margin: 0;
    color: var(--nx-rp-ink);
}

.nx-rp-open-amount > b {
    font-size: var(--nx-font-4xl);
    font-weight: var(--nx-weight-bold);
    line-height: 1.15;
    letter-spacing: -.5px;
}

.nx-rp-open-amount > i {
    font-style: normal;
    font-size: var(--nx-font-md);
    color: var(--nx-rp-gold);
}

.nx-rp-open-stored {
    margin: 0;
    font-size: var(--nx-font-sm);
    color: rgba(255, 246, 230, .78);
}

.nx-rp-open-best {
    margin: 0;
    padding: var(--nx-space-1) var(--nx-space-4);
    border-radius: var(--nx-radius-full);
    background: linear-gradient(120deg, #ffedc2, var(--nx-rp-gold));
    font-size: var(--nx-font-sm);
    font-weight: var(--nx-weight-semibold);
    color: #8c2a12;
}

.nx-rp-open-detail {
    margin-top: var(--nx-space-2);
    padding: var(--nx-space-2) var(--nx-space-5);
    border: 1px solid rgba(242, 200, 119, .66);
    border-radius: var(--nx-radius-full);
    color: var(--nx-rp-gold);
    font-size: var(--nx-font-sm);
    text-decoration: none;
    transition: background-color .2s ease;
}

.nx-rp-open-detail:hover {
    background: rgba(255, 246, 230, .14);
    color: var(--nx-rp-ink);
    text-decoration: none;
}

/* ── 封口 + 火花 ──────────────────────────────────────────────────────── */
.nx-rp-open-flap {
    position: absolute;
    top: 5px;
    right: 5px;
    left: 5px;
    height: 40%;
    z-index: 2;
    border-radius: var(--nx-radius-lg) var(--nx-radius-lg) 0 0 / var(--nx-radius-lg);
    background: linear-gradient(180deg, var(--nx-rp-cover-deep), #941f16);
    box-shadow: inset 0 -1px 0 rgba(242, 200, 119, .55);
    transform-origin: top center;
    transition: transform .5s cubic-bezier(.4, .1, .2, 1), opacity .3s ease .22s;
}

/* 封口上的金印 */
.nx-rp-open-flap::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -13px;
    width: 26px;
    height: 26px;
    margin-left: -13px;
    border-radius: 50%;
    background: radial-gradient(circle at 36% 30%, #ffedc2, var(--nx-rp-gold) 62%, var(--nx-rp-gold-deep));
    box-shadow: var(--nx-shadow-sm);
}

.nx-rp-open.js:not(.is-open) .nx-rp-open-flap { transform: rotateX(0deg); }

.nx-rp-open.js.is-open .nx-rp-open-flap {
    transform: rotateX(-118deg);
    opacity: 0;
}

.nx-rp-open-sparks {
    position: absolute;
    left: 50%;
    top: 42%;
    width: 0;
    height: 0;
    z-index: 4;
    pointer-events: none;
}

.nx-rp-open-sparks > i {
    position: absolute;
    left: -3px;
    top: -3px;
    width: 6px;
    height: 6px;
    border-radius: var(--nx-radius-full);
    background: var(--nx-rp-gold);
    opacity: 0;
}

/* 角度 / 距离 / 延迟由 redpacket.js 写成每个 <i> 的行内变量 */
.nx-rp-open.js.is-open:not(.no-fx) .nx-rp-open-sparks > i {
    animation: nx-rp-spark 780ms var(--nx-rp-spark-delay, 0ms) ease-out both;
}

/* ── 抖动 ─────────────────────────────────────────────────────────────── */
.nx-rp-open.is-shake .nx-rp-open-card { animation: nx-rp-shake 520ms ease-in-out; }

@keyframes nx-rp-shake {
    0%, 100% { transform: rotate(0deg) translateX(0); }
    15% { transform: rotate(-5deg) translateX(-4px); }
    30% { transform: rotate(5deg) translateX(4px); }
    45% { transform: rotate(-4deg) translateX(-3px); }
    60% { transform: rotate(3deg) translateX(2px); }
    80% { transform: rotate(-1.5deg) translateX(-1px); }
}

@keyframes nx-rp-open-pulse {
    0%, 100% { box-shadow: var(--nx-shadow-md), 0 0 0 0 rgba(255, 246, 230, .45); }
    55% { box-shadow: var(--nx-shadow-md), 0 0 0 11px rgba(255, 246, 230, 0); }
}

@keyframes nx-rp-spark {
    0% {
        opacity: 0;
        transform: rotate(var(--nx-rp-spark-angle, 0deg))
                   translateY(var(--nx-rp-spark-dist, 36px)) scale(.3);
    }
    22% { opacity: 1; }
    100% {
        opacity: 0;
        transform: rotate(var(--nx-rp-spark-angle, 0deg))
                   translateY(calc(-1.9 * var(--nx-rp-spark-dist, 36px))) scale(1);
    }
}

/* 系统要求减少动效 / 本会话已经拆过：直接是终态，没有过渡也没有抖动 */
.nx-rp-open.no-fx .nx-rp-open-card,
.nx-rp-open.no-fx .nx-rp-open-btn,
.nx-rp-open.no-fx .nx-rp-open-flap,
.nx-rp-open.no-fx .nx-rp-open-back,
.nx-rp-open.no-fx .nx-rp-open-front,
.nx-rp-open.no-fx .nx-rp-open-detail {
    animation: none !important;
    transition: none !important;
}

@media (prefers-reduced-motion: reduce) {
    .nx-rp-open-card,
    .nx-rp-open-flap,
    .nx-rp-open-back,
    .nx-rp-open-front,
    .nx-rp-open-btn {
        animation: none !important;
        transition: none !important;
    }
}

@media (max-width: 480px) {
    .nx-rp-open-card { padding: var(--nx-space-6) var(--nx-space-5); }
    .nx-rp-open-amount > b { font-size: var(--nx-font-3xl); }
}
