@charset "UTF-8";
/* ============================================================
   torrent 影视/游戏/软件资源门户 —— 前台样式(单文件, 自包含)

   【设计来源】设计 token(颜色/圆角/阴影/字体栈)逐字提炼自
   shared_admin/css/ui-kit.css:11-18, 组件观感(卡片/按钮/表格/pill/输入框)
   按 ui-kit 同一套配方复刻 —— 目标是"和 erp 后台看起来是同一个产品"。

   【为什么不直接 <link> ui-kit.css】(ui-kit.css 其实已经躺在本 webapp 的
   dist/css/ 里, build.xml copy-admin-www 把整个 shared_admin 平铺过来了, 所以
   这是"能引但不引")：
     1. ui-kit.css:25 有 `@media(min-width:769px){html{zoom:.9}}` —— 桌面端整站
        压到 90%。门户是要进搜索索引的, 14px 正文渲染成 ~12.6px 会踩 Lighthouse
        "字号过小/点击目标过小"审计; 且 zoom 非标准, 会污染所有 vh/vw 计算
        (后台已为它打了两个补丁: ui-kit.css:35、:116)。见本文件"吸底 footer"注释。
     2. ui-kit.css 294 行里大半是 .uk-* 后台外壳 + Bootstrap 类覆盖, 而前台不引
        Bootstrap —— 那些 !important 空转, 但 Bootstrap 提供的 padding 也一并
        消失(.btn/.form-control 在 ui-kit 里只有 radius/字重/字号/边框色, 没有
        padding), 反而要在这里补回来。所以不如只搬 token。
     3. 解耦: ui-kit.css 是三个后台的唯一真源, 后台改视觉不该静默改动 SEO 前台。
   【改主色】改下面 :root 的 --primary / --primary-hover / --primary-weak 三个值,
   全站(按钮/链接/激活导航/焦点光圈/选区)一起变; 其它地方不要写死颜色。
   【无 JS 依赖】SEO 范式 A: 内容服务端渲染, 样式不靠 JS 才成型。本文件不含任何
   需要 JS 打标(data-theme / x-cloak / .is-xxx)才生效的规则。

   【注释里引用行号的口径】(2026-07-30 定, 起因见下)
     - **ui-kit.css 写行号**: 它是本站视觉的唯一基准, 且不随本项目的迭代变动, 行号可信、可核。
       下面每一处"和 erp 对齐"的值都带 `ui-kit.css:行号`, 复核时逐条 diff 得动。
     - **本目录的 JSP 只按结构指路, 不写行号**: 门户 5 个页面 + header/footer 片段本轮被大量重构
       (同一批改动里 detail.jsp 的行号漂了三次), 写死行号的注释半天就全指错地方 —— 比没有注释更坏,
       因为读的人会照着错行号下结论。所以一律写成"detail.jsp 的 <ul class=\"attrs\">"这种结构描述,
       类名契约本身是稳定的, 照描述 grep 一次就能定位。
   ============================================================ */

/* ---------- 设计 token(ui-kit.css:11-18 逐字, 剔除后台壳专用的 --sidebar) ---------- */
:root {
    /* 面 / 线 —— ui-kit.css:11 */
    --bg: #f6f7f9;
    --surface: #fff;
    --surface-2: #fafbfc;
    --hover: #f4f5f8;
    --border: #e7e9ee;
    --border-2: #eef0f4;
    /* ui-kit 里没 token 化的两个硬编码值, 这里提升成变量(值不变):
       #d3d7e0 = 输入框 hover 边框(:221) + 滚动条 thumb(:30); #b9bfcc = thumb hover(:222) */
    --border-strong: #d3d7e0;
    --border-strong-2: #b9bfcc;

    /* 文字 —— ui-kit.css:12 */
    --text: #1a1f2b;
    --muted: #6b7385;
    --faint: #9aa1b1;

    /* 主色 —— ui-kit.css:13(改主色只改这三行) */
    --primary: #4263eb;
    --primary-weak: #eef1fe;
    --primary-hover: #3651c9;

    /* 语义色 + weak 底 —— ui-kit.css:14。整组照抄不裁剪: 本文件目前只用到 warn
       (卡片更新状态 / 电驴风险提示), --ok/--danger 和 --sh-lg 先留着 —— 将来加
       成功提示、失效资源标记、弹层时直接取, 免得有人现场发明新颜色。 */
    --ok: #12b76a;
    --ok-weak: #e7f7ee;
    --warn: #f79009;
    --warn-weak: #fef3e2;
    --danger: #f04438;
    --danger-weak: #fdeceb;

    /* 圆角三档 —— ui-kit.css:15 */
    --r-lg: 12px;
    --r: 9px;
    --r-sm: 6px;

    /* 阴影三档 —— ui-kit.css:16 */
    --sh-sm: 0 1px 2px rgba(16, 24, 40, .06);
    --sh: 0 4px 16px rgba(16, 24, 40, .07);
    --sh-lg: 0 12px 32px rgba(16, 24, 40, .12);

    /* 字体栈 —— ui-kit.css:18 */
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
}

/* 暗色: erp 线上实际是 light-only(ui-kit.css:230-237 的 [data-theme=dark] 规则在,
   但切换钮 2026-07-10 已被砍, 触发它的前置脚本压根不存在), 所以前台也 light-only,
   保持"同一个产品"。将来要上暗色: 加一个 @media(prefers-color-scheme:dark){:root{...}}
   把 ui-kit.css:230-237 的变量体粘进去即可(别学后台那套 localStorage + 阻塞内联脚本,
   SSR 门户上会拖 FCP 且无法按用户缓存变体)。注意暗色块只换了 *-weak 没换
   --ok/--warn/--danger 本色, 真要上得自己复核一遍对比度。 */

/* ---------- 基础规则(ui-kit.css:20-30 的前台版) ---------- */
* { box-sizing: border-box; }

/* ‼️ 布局 bug 修复 1 / 共 2 —— "footer 之后一大片空白"
   旧写法: body 没有任何高度约束, .site-footer 只有 margin-top:40px, 内容不足一屏时
   footer 就停在内容末尾, 下面留一大片 body 背景色。
   正确做法(教科书三行 flex 吸底): body 撑满视口高度 + 列向 flex, 中间区 flex:1 0 auto
   吃掉剩余高度, footer flex:none 永远贴在下沿; 内容超屏时 footer 自然跟在文末。
   两个坑都避开了:
     - 不抄 ui-kit.css:21 的 `html,body{margin:0;height:100%}` —— height 是硬高度, body
       被钉死一屏, 内容超出后 flex 链失效; 前台要 min-height。
     - 不用 position:sticky/fixed 冒充吸底(sticky 内容不足时不会下沉, 正是"footer 后
       一片白"的另一种典型成因; fixed 会盖住文末内容)。
   这里 vh/dvh 可以放心用: 本文件没抄 zoom:.9, 所以不需要 ui-kit.css:35 那种
   `calc(100vh / .9)` 反除补偿。 */
html {
    min-height: 100%;
}

body {
    margin: 0;
    min-height: 100vh;      /* 旧内核兜底 */
    min-height: 100dvh;     /* dvh 治移动端地址栏伸缩 */
    display: flex;
    flex-direction: column;
    font-family: var(--font);
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
    line-height: 1.5;
    -webkit-font-smoothing: antialiased;
}

/* ui-kit.css:27: 链接不蓝不下划线, 靠上下文着色(卡片/导航整块可点, 蓝链会很脏);
   正文里真正需要被认出来的链接在下面单独着 --primary。 */
a { color: inherit; text-decoration: none; }

img { max-width: 100%; }

/* 滚动条 / 选区 —— ui-kit.css:29-30 + :222 + :219 */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 6px; }
::-webkit-scrollbar-thumb:hover { background: var(--border-strong-2); }
::selection { background: var(--primary-weak); }

/* 键盘焦点环 —— ui-kit.css:196 的配方(a11y: 只在键盘操作时出现, 鼠标点击不出) */
a:focus-visible,
button:focus-visible,
.btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 1px var(--primary), 0 0 0 4px var(--primary-weak);
}

/* 动效偏好 —— ui-kit.css:224 逐字 */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* ---------- 组件: 状态 pill(一套配方 —— ui-kit.css:82-84) ---------- */
/* ‼️ 复核修复(中危)"pill 体系碎成 5 套参数, 且 erp 最有辨识度的圆点全站没有":
   后台只有 .uk-pill 一条配方(ui-kit.css:82) + 一个 ::before 圆点(:83) + 三个语义变体(:84),
   而本文件原来七个挂载点各写一套: padding 3px 10px / 2px 9px / 1px 8px / 1px 7px 四种,
   圆角 20px 与 var(--r-sm) 两种, 字号 12px 与 12.5px 两种, 字重 600 与 500 两种 ——
   并排看就不像同一个产品。这里把四个值收敛到一处, 各挂载点只保留"选哪组语义色"和自己的定位外边距。
   ‼️ 为什么写成"既有类名的选择器列表"而不是新增一个 .pill 基类: 不能改 JSP(类名契约变更要另开一轮),
      所以基类只能以选择器列表的形式存在。将来 JSP 能改时, 把列表换成 .pill 即可, 值不用动。
   ‼️ 位置不能挪到下面去: 列表里每条都是 0-2-0, 和后面各组件自己的规则同特异性, 靠源序决定胜负 ——
      基类必须排在前面, 后面的组件规则才能覆盖它(例如 .user-box .me 要把 display 换回 inline-block)。 */
.user-box .me,
.page-title .total,
.links .cnt,
.card .status,
.link-table .grp,
.link-table .pwd,
.link-table .warn {
    display: inline-flex;       /* ui-kit.css:82 */
    align-items: center;        /* ui-kit.css:82 */
    gap: 5px;                   /* ui-kit.css:82 —— 圆点与文字的间距 */
    padding: 3px 10px;          /* ui-kit.css:82 */
    border-radius: 20px;        /* ui-kit.css:82 */
    font-size: 12px;            /* ui-kit.css:82 */
    font-weight: 600;           /* ui-kit.css:82 */
    /* ui-kit 里 pill 只出现在表格单元格中, 不需要这条; 本文件的 .total/.cnt 挂在 h1/h2 里,
       要抵消标题继承来的 -.01em 字距, 否则同一个 pill 在标题里和表格里字距不一样。 */
    letter-spacing: 0;
}

/* currentColor 小圆点 —— ui-kit.css:83 逐字。这是 erp pill 最有辨识度的一笔, 原来全站一个没有。
   只给"状态语义"pill: 卡片的更新状态、电驴链接的风险提示 —— 对应 ui-kit.css:84 那三个变体
   (ok/warn/dng)全是状态语义。纯计数(.total/.cnt)、纯标签(.grp/.pwd)和用户名(.me)不带点:
   后台的计数走的是 ui-kit.css:46 的 .badge, 本来就没有圆点。
   flex:none 是本文件的补充(ui-kit.css:83 没写): 后台的 pill 永不折行, 而 .warn 是一整句会折行的
   文案, 圆点若可收缩就会被压成椭圆。 */
.card .status::before,
.link-table .warn::before {
    content: "";
    width: 6px;
    height: 6px;
    flex: none;
    border-radius: 50%;
    background: currentColor;
}

/* ---------- 栅格容器 ---------- */
/* width:100% + margin:0 auto 是给 flex 子项居中用的(body 是列向 flex 容器,
   交叉轴上的 auto 外边距会吸收剩余空间 = 水平居中); 只写 max-width 不写 width
   在部分内核里会被 stretch 拉满, 保险起见都写上。 */
.wrap {
    width: 100%;
    max-width: 1180px;
    margin: 0 auto;
    padding: 0 16px;
}

/* ---------- 顶栏 ---------- */
/* 观感取 erp topbar: 白面 + 1px 下边线, 不是原来那块深色 #1f2430 —— 后台整套是
   浅色 SaaS 风, 深色顶栏会立刻显得是两个产品。sticky 吸顶(没有 zoom, top:0 可信)。 */
.site-header {
    flex: none;
    position: sticky;
    top: 0;
    z-index: 20;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
}

.header-inner {
    display: flex;
    align-items: center;
    gap: 16px;
    min-height: 58px;
    /* 窄屏换行处理见文末 <=640px 断点; 这里不写死 height, 换行时才不会把内容挤出去 */
}

/* 站名 —— 字号/字重/字距同 ui-kit.css:37 的 .uk-brand, 前面那块渐变方块是
   ui-kit.css:38 唯一值得搬到前台的强视觉(纯 CSS 伪元素, 不加标签不加图片)。
   ‼️ 清理(复核点名的死规则之一): 原来这里并挂了一条过渡期兼容选择器 `.header-inner > .logo`
   (含它的 ::before 和移动断点里的两条)。已核实 header.jsp:27 是 `<a class="brand" href="/">`,
   契约类名 .brand 已落地, 全仓 grep 无第二处 class="logo" 会命中本文件(news/tool.jsp 有一个,
   但那是另一个站、不引本文件), 所以整条兼容选择器删掉 —— 留着会让下一个人以为 .logo 还在用。 */
.brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;                  /* ui-kit.css:37 */
    flex: none;
    font-size: 17px;            /* ui-kit.css:37 */
    font-weight: 700;           /* ui-kit.css:37 */
    letter-spacing: -.01em;     /* ui-kit.css:37 */
    color: var(--text);
    white-space: nowrap;
}

/* ‼️ 复核修复(低危)"品牌方块和 erp 不是一个尺寸, 而且是个空块": ui-kit.css:38 的 .uk-brand .logo
   是 30px 方块 + 内部 flex 居中一个 16px 白色字形(同一手法在 erp 线上壳里还有一处:
   shared_admin/js/ui-kit.js:82 的 .uk-user .ava 也是色块里放一个字, 见 ui-kit.css:52) ——
   原来这里只搬了渐变和 8px 圆角, 尺寸 26px 且块内空白, 顶栏第一眼的品牌区就对不上
   (同样 8px 圆角配 26px 与配 30px 的角半径占比也不同, 并排看形状都不一样)。
   现在尺寸对齐 30px, 并补上 ui-kit.css:38 后半段的 flex 居中 + #fff + 16px; 字形受限于不能改 JSP,
   只能由伪元素出一个"影"(站名首字, 和 .ava 取用户名首字同一个思路)。 */
.brand::before {
    content: "影";
    /* 双写做渐进增强(同本文件下面 max-height 的 vh/dvh 手法): 支持 content alt 文本的内核按第二行
       生效, 读屏器把伪元素当纯装饰跳过 —— 无障碍名保持"影视资源门户"而不是"影影视资源门户";
       不支持的内核整行丢弃、回退到上一行, 方块和字形照旧显示。两行顺序不能颠倒。 */
    content: "影" / "";
    width: 30px;                /* ui-kit.css:38 */
    height: 30px;               /* ui-kit.css:38 */
    flex: none;                 /* ui-kit.css:38 */
    border-radius: 8px;         /* ui-kit.css:38 */
    background: linear-gradient(135deg, var(--primary), #7c8cf7);   /* ui-kit.css:38 逐字 */
    /* ui-kit.css:38 写的是 display:flex; 伪元素在 .brand(inline-flex)里本身已是 flex 项,
       用 inline-flex 等效且不依赖父容器是什么 display, 内部居中效果一致。 */
    display: inline-flex;
    align-items: center;        /* ui-kit.css:38 */
    justify-content: center;    /* ui-kit.css:38 */
    color: #fff;                /* ui-kit.css:38 */
    font-size: 16px;            /* ui-kit.css:38 */
    line-height: 1;             /* 30px 方块内靠 flex 居中, 行高不该参与; 写 1 防某些内核用 1.5 行高把字顶偏 */
}

/* 搜索框 —— 配方 ui-kit.css:59-60 的 .search, 外壳描边 + 内部 input 无边框。
   ‼️ 布局 bug 修复 2 / 共 2 —— "搜索框硬撑":
   旧写法 `flex:1` 简写带 flex-basis:0% 且没有 min-width:0, input 的默认
   intrinsic 宽度(约 20 字符)会把 flex 项撑破, 窄屏顶栏直接溢出横向滚动。
   这里 flex:1 1 260px 给理想宽度、min-width:0 允许收缩、max-width 限制上限,
   三件套齐了才不会既撑破也不会独占整行。 */
.search-box {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 260px;
    min-width: 0;
    max-width: 520px;
    /* ‼️ 复核修复(中危)"搜索框看不出是输入区": 原来这里写的是 background:var(--surface)(#fff),
       而顶栏(上面 .site-header)也是 var(--surface) —— 白压白, 只剩一条 #e7e9ee 的 1px 边(对白底约 1.15:1)。
       上面注释自称照 ui-kit.css:59 的配方, 但那条是 background:var(--bg) 灰底压在白顶栏上(一眼
       就是个输入槽), 值没搬全。这里把底色和壳上的 color 都补齐, 观感回到和后台一致。
       ‼️ 顺带钉一笔, 免得下一轮再被误判成"深顶栏语境": 本站顶栏是**浅色** —— 上面 .site-header 的
       background 就是 var(--surface), 和 erp 的 .uk-topbar(ui-kit.css:56 也是 var(--surface))同色。
       深色 #1f2430 顶栏是本文件更早的写法, 已经被替换掉了(见 .site-header 上方注释)。所以这里直接
       照 ui-kit.css:59 用 var(--bg) 灰底就得到和后台一模一样的"凹陷输入槽", 不需要为深顶栏另设一套。
       ‼️ 与 ui-kit.css:59 唯一**有意**不一致的一项, 写在这里免得下一轮又被当成"值没搬全": 控件总高。
       erp 的 .uk-search 壳里只有一个无边框 input(≈32px 高), 提交靠 JS; 门户按 SEO 范式 A 必须能在
       无 JS 下提交, 所以壳里多了一个真 <button type=submit>(header.jsp:33), 撑到 ≈40px。
       这 8px 差额是"必须有提交钮"带来的, 不是配方跑偏 —— 而且 40px 正好压住 Lighthouse 的
       "点击目标过小"审计门槛(和文末移动断点里 .pager a 撑 min-height:40px 是同一条门户独有的理由,
       文件头也为此放弃了 ui-kit.css:25 的 zoom:.9)。除高度外, 底色/描边/圆角/内边距/字号全部与
       ui-kit.css:59-60 逐值一致。 */
    background: var(--bg);
    color: var(--muted);
    border: 1px solid var(--border);
    border-radius: var(--r);
    padding: 4px 5px 4px 12px;
    transition: border-color .15s, box-shadow .15s;
}

/* 输入框 hover 边框 = ui-kit.css:221; focus 光圈 = 3px + --primary-weak(ui-kit.css:112)。
   用 :focus-within 把光圈画在外壳上, 视觉上和后台的输入框一模一样。 */
.search-box:hover:not(:focus-within) { border-color: var(--border-strong); }

.search-box:focus-within {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-weak);
}

.search-box input {
    flex: 1 1 auto;
    min-width: 0;
    border: 0;
    background: transparent;
    outline: 0;
    font-family: inherit;
    font-size: 13px;   /* 复核修复(中危): 对齐 ui-kit.css:60 的 .uk-search input{font-size:13px}, 原来是 13.5px */
    color: var(--text);
    padding: 5px 0;
}

.search-box input::placeholder { color: var(--faint); opacity: 1; }   /* ui-kit.css:220 */

/* 搜索按钮 = 小号实心主色钮(值同 .btn-primary + .btn-sm) */
.search-box button {
    flex: none;
    border: 1px solid var(--primary);
    border-radius: var(--r-sm);
    background: var(--primary);
    color: #fff;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    padding: 6px 14px;
    cursor: pointer;
    transition: background-color .15s, border-color .15s;
}

.search-box button:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

/* 登录态 —— 灰字, hover 才上主色(顶栏不该有第二块蓝) */
.user-box {
    margin-left: auto;
    flex: none;
    display: flex;
    align-items: center;
    gap: 12px;
    white-space: nowrap;
    font-size: 13.5px;
}

.user-box a { color: var(--muted); }
.user-box a:hover { color: var(--primary); }

/* 用户名不是链接, 用 pill 底衬一下和"退出"区分。尺寸/圆角/字号/字重全部走上面那套 pill 基配方
   (ui-kit.css:82), 这里只挑"中性 mute"这组色 + 自己的截断行为。
   ‼️ display 必须在这里改回 inline-block(基类给的是 ui-kit.css:82 的 inline-flex):
   text-overflow 只对块级内容盒生效, flex 容器里的文字是匿名 flex 项, 省略号不会出来。
   这条能压住基类不是靠特异性(两边都是 0-2-0), 是靠源序在后 —— 别把 pill 基配方挪到本行之后。 */
.user-box .me {
    display: inline-block;
    max-width: 10em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: var(--hover);
    color: var(--muted);
}

/* ---------- 中间弹性区(吸底 footer 的中段) ---------- */
/* ‼️ 清理(复核点名的死规则之二): 原来这里并挂了过渡期兼容选择器 `body > main`, 用来兜住"JSP 还写着
   <main class="wrap"> 没加 .site-main"的情况。已逐页核实 5 个页面全部同步完毕
   (index / search / detail / play / 404 五页的 <main> 都带 class="site-main"), 兼容选择器已成死代码, 删掉。
   flex:1 0 auto 而不是 flex:1 —— 简写会带 flex-basis:0%, 长内容在某些内核里被压。 */
.site-main {
    flex: 1 0 auto;
    padding-bottom: 32px;
}

/* ---------- 类型导航 ---------- */
/* 胶囊 chip: 白面 + 1px 描边 + 20px 全圆角(同 pill 的圆角语言), 选中态 = 主色弱底 + 主色字。
   ‼️ 复核修复(中危)"选中态的视觉语言和 erp 正好倒过来": 原来这里是实心主色 + 白字, 而 erp 的选中态
   通篇都是"弱底染色 + 主色字 + 600", 三处互相印证:
     - ui-kit.css:44  .uk-nav .nav-item.active{background:var(--primary-weak);color:var(--primary);font-weight:600}
     - ui-kit.css:164 .cs-item.on,.cs-item.active{background:var(--primary-weak)}
     - ui-kit.css:293 select option:checked{background:var(--primary-weak);color:var(--primary);font-weight:600}
   而"实心主色"在 erp 里被留给了另外两种语义: 主动作按钮(ui-kit.css:102 .btn-primary)和
   分页当前页(ui-kit.css:137)。门户把实心用在导航上, 等于把 erp 的两套语义调了个头 ——
   这和 .pager .cur 那处(见下面分页段)是同一个 bug 的两半, 本轮**同时**改, 方向对齐 erp。
   ‼️ 关于 ui-kit.css:45 那条 ::before 左侧 3px 主色条: 本组件**不做**等效处理(不加下边框条)。理由:
     1. 那条 3px 条在 ui-kit 里只出现一次, 且只挂在 .uk-nav(竖排侧栏列表)上 —— 它是"整行贴着侧栏
        左沿"这个形态的边缘标记。上面另外两处选中态(.cs-item.on / option:checked)都没有它,
        说明 erp 的选中态里"弱底 + 主色字"才是承重的信号, 3px 条是 .uk-nav 的局部装饰。
     2. 本组件是 20px 全圆角的横排 chip, 一条 3px 直边落在圆角胶囊底部, 要么被圆角切断、要么得
        额外开 overflow 裁剪, 会造出一个 ui-kit 里不存在的形状 —— 那才是真的偏离 erp。 */
.type-nav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 18px 0 4px;
}

.type-nav a {
    padding: 6px 15px;
    border-radius: 20px;
    border: 1px solid var(--border);
    background: var(--surface);
    color: var(--muted);
    font-size: 13.5px;
    font-weight: 500;
    transition: background-color .15s, border-color .15s, color .15s;
}

.type-nav a:hover {
    background: var(--hover);
    border-color: var(--border-strong);
    color: var(--text);
}

.type-nav a.on {
    background: var(--primary-weak);    /* ui-kit.css:44 */
    color: var(--primary);              /* ui-kit.css:44 */
    font-weight: 600;                   /* ui-kit.css:44 */
    /* erp 的 .nav-item 没有边框, 整块就是一片弱底; 本组件的 chip 有 1px 描边, 所以把边框色也刷成
       --primary-weak, 轮廓才会和 erp 一样融成一整片弱底(刷成 --primary 会变成"描边胶囊", 不是 erp 的样子)。 */
    border-color: var(--primary-weak);
}

/* ‼️ 原来这里还有一条 .type-nav a.on:hover{background:var(--primary-hover)}, 已删。
   erp 的选中项悬停时**不变色**: ui-kit.css:43 的 :hover 与 :44 的 .active 特异性同为 0-3-0,
   .active 源序在后所以压住了 hover。本文件同构 —— .type-nav a:hover(0-2-1) 与 .type-nav a.on(0-2-1)
   特异性也相等, .on 源序在后, 天然就压住了上面那条 hover, 不需要再写第三条规则。 */

/* ---------- 页面标题 ---------- */
.page-title {
    margin: 16px 0 16px;
    font-size: 20px;
    font-weight: 700;
    letter-spacing: -.01em;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

/* play.jsp 的标题里是回详情页的链接 */
.page-title a { color: inherit; }
.page-title a:hover { color: var(--primary); }

/* 计数不参与标题字重, 降级成 mute pill —— 尺寸/圆角/字号/字重/字距全部走上面那套 pill 基配方
   (ui-kit.css:82), 这里只挑"中性 mute"这组色。原来这条自己写了 2px 9px 的 padding, 和另外四处
   pill 各不相同, 已收敛。play.jsp 的 h1 里也用它挂"链接标题"(不只是计数), 所以不带圆点是对的。 */
.page-title .total {
    background: var(--hover);
    color: var(--muted);
}

/* ---------- 空态 ---------- */
/* 配方 ui-kit.css:205-206。契约类是 .empty-state(带 .ico/.tit/.sub 三段)。
   ‼️ 清理(复核点名的死规则之三): 原来这里(以及下面 .empty a 和移动断点里)并挂了裸 .empty,
   兜"JSP 还写着 <p class="empty">"的过渡期。已反向 grep 全仓确认 JSP 侧再无 class="empty"
   (index / search / detail 三页只在**注释**里提到"不再用裸 <p class=\"empty\">"), 三处兼容选择器一并删掉。 */
.empty-state {
    padding: 48px 20px;         /* ui-kit.css:205 */
    text-align: center;         /* ui-kit.css:205 */
    color: var(--faint);        /* ui-kit.css:205 */
    font-size: 13.5px;
    margin: 0;
}

.empty-state .ico {
    display: block;             /* ui-kit.css:206 */
    font-size: 28px;            /* ui-kit.css:206 */
    line-height: 1;
    /* 复核修复: 原来是 10px, ui-kit.css:206 的 .uk-empty .ic 是 margin-bottom:8px —— 四个页面的
       空态图标到标题的距离比后台松一档, 收回 8px 对齐。 */
    margin-bottom: 8px;
    opacity: .55;               /* ui-kit.css:206 */
}

/* ‼️ 追加修复(本轮新发现, 起因是 JSP 侧在本文件写完之后又改了空态图标的结构):
   .ico 现在是 <div class="ico" aria-hidden="true"> 里包一个 28×28 的内联 <svg>(index / search / detail / 404
   四页同构, feather 风 24 viewBox + stroke="currentColor", 同 ui-kit.css:64 的 .uk-i 那套画法),
   不再是原来那种"span 里放一个字形"。内联 SVG 默认是 inline-level, 要坐在文字基线上, 基线下方还会
   留一截 descender 空隙(28px 字号下约 5-6px) —— 于是 .ico 的实际盒高 > 28px, 上面那条对齐
   ui-kit.css:206 的 margin-bottom:8px 渲染出来变成 13-14px, 四个页面的空态又比后台松一档
   (和上一轮修 UA 的 <p> 外边距是同一类问题, 只是换了个来源)。
   erp 侧知道这个基线坑: ui-kit.css:64 的 .uk-i 给内联图标补了 `vertical-align:-2px` 去抵消它 ——
   但那是 16px 图标混排在文字行里的场景; 这里是一个独占一行的 28px 装饰图标, 直接 display:block
   让它不参与基线更干净(盒高正好 28px, 不用去猜 -2px 该配几)。
   块级元素不再吃 .empty-state 的 text-align:center(ui-kit.css:205), 所以 margin:0 auto 补回水平居中。
   width/height 有意不在这里写死: <svg> 标签自带 width="28" height="28", 和上面 .ico 的 font-size:28px
   (ui-kit.css:206)是同一个 28, 再写第三遍就是三处真源。 */
.empty-state .ico svg {
    display: block;
    margin: 0 auto;
}

.empty-state .tit {
    display: block;
    color: var(--text);
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 6px;
}

.empty-state .sub { display: block; color: var(--muted); font-size: 13px; }

/* ‼️ 复核修复(低危)"空态间距不是写的那个数": .tit/.sub 在 4 个页面(index / search / detail / 404)里都是 <p>,
   本文件没有通用
   p 复位(文件开头那条 * 只给了 box-sizing), UA 的 1em 上下外边距原样生效: .ico 的 10px 与 .tit 的 15px
   相邻外边距合并成 15px、.tit 的 6px 与 .sub 的 13px 合并成 13px, .sub 底部那 13px 又叠在
   容器 48px padding 上(下 61px / 上 48px, 视觉重心下坠)。清掉 UA 外边距, 间距就回到上面
   声明的 8px / 6px(.ico 的 8px 见上面注释, 对齐 ui-kit.css:206)。
   ‼️ 只复位 .empty-state 内的 p, 不写全局 p{margin:0}: 详情页 .intro 里的简介正文也是 <p>,
   全局复位会连它的段间距一起清掉(它自己在 .intro p 里另有 margin:0 的声明, 但将来简介改成多段
   时就要靠 UA 段间距, 别提前埋雷)。 */
.empty-state p { margin: 0; }

/* ---------- 卡片列表 ---------- */
.card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 16px;
    grid-template-columns: repeat(auto-fill, minmax(164px, 1fr));
}

/* 卡片观感 = ui-kit.css:99 的 .card: 1px 描边 + 12px 圆角 + 极淡 --sh-sm,
   不是"无边框大阴影"那派。ui-kit 没有卡片 hover 抬升, 前台列表需要可点反馈,
   所以只升一级到已有 token(--sh + --border-strong), 不自创阴影值。 */
.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-sm);
    overflow: hidden;
    transition: box-shadow .15s, border-color .15s;
}

.card:hover { box-shadow: var(--sh); border-color: var(--border-strong); }

.card a { display: block; color: inherit; }

/* ‼️ 复核修复(中危, WCAG 2.4.7)"卡片键盘焦点不可见": 上面 .card 的 overflow:hidden(裁 .poster 圆角,
   不能删)会在 .card 的 padding box 边缘裁剪, 而 .card 无 padding + .card a 是 display:block 的唯一子元素
   -> a 的 border box 恰好等于该裁剪边界, 文件开头那条全站焦点环(a:focus-visible, outline:none + 向外扩散 1px/4px 的
   box-shadow)整圈落在边界之外被吃光, Tab 到卡片时零像素反馈。这里改用 outline 负偏移把环画进内侧
   (outline 不参与布局, 负 offset 后位于 padding box 以内, 不会被祖先裁掉), 并关掉那圈必被裁的阴影。
   ‼️ 本轮复核结论: 这条**确实可见**(2px 环整体位于裁剪边界内侧 3px 处), 上一轮的修法成立, 没有回退。
   只补一处收尾: 加 border-radius —— .card 的裁剪曲线是圆角的(内圆角 = --r-lg 12px 减 1px 边框 = 11px),
   而 <a> 本身没有圆角, 直角环的四个角会伸到那条曲线外侧被切掉四个小缺口。outline 会跟随元素的
   border-radius(负 offset 时半径按 offset 收缩), 给 a 补上同一档圆角后四角就贴着曲线走、环是完整的。
   注意: 只在 :focus-visible 上给圆角, .card a 常态不加 —— 它没有背景也没有边框, 加了没意义。 */
.card a:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -3px;
    border-radius: var(--r-lg);
    box-shadow: none;
}

.card .poster {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    background: var(--hover);   /* 图未加载/占位 SVG 时的底色, 别露白 */
}

.card .meta { padding: 10px 12px 12px; }

.card .title {
    display: block;
    font-size: 13.5px;
    font-weight: 600;
    line-height: 1.4;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    transition: color .15s;
}

.card a:hover .title { color: var(--primary); }

/* 更新状态("更新至12集")= warn 语义 pill: weak 底 + 强色字, 配方同 ui-kit.css:84 的 .uk-pill.warn。
   尺寸/圆角/字号/字重和 currentColor 圆点都走上面那套 pill 基配方(ui-kit.css:82-83), 这里只挑色 +
   自己的定位外边距。原来这条自己写了 1px 8px 的 padding 且没有圆点, 是全站 pill 里最矮的一个。
   display 不再声明: 基配方给的 inline-flex 就是要的(ui-kit.css:82), 圆点得靠它当 flex 项。 */
.card .status {
    margin-top: 6px;
    background: var(--warn-weak);   /* ui-kit.css:84 */
    color: var(--warn);             /* ui-kit.css:84 */
}

.card .sub {
    display: block;
    margin-top: 5px;
    font-size: 12px;
    color: var(--faint);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------- 分页 ---------- */
/* 前后页是真链接(SEO 靠 rel=prev/next 理解序列)。整组的尺寸配方 = 后台翻页器 ui-kit.css:135
   (`--bs-pagination-padding-x:.6rem; --bs-pagination-padding-y:.22rem; --bs-pagination-font-size:12.5px`),
   未选中项配色 = ui-kit.css:136 的 .page-link(muted 字 + --border 边 + --surface 底),
   当前页 = ui-kit.css:137 的实心主色。 */
.pager {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 10px;
    padding: 28px 0 8px;
}

/* ‼️ 复核修复(低危)"分页控件比 erp 胖近一倍": 原来是 padding:7px 15px / 13.5px / 600, 三个值一个
   都没对上 ui-kit.css:135 的 .22rem .6rem / 12.5px。注意这不是 zoom .9 的反向补偿 —— 本文件没抄
   zoom(见文件头), 而且 12.5px 按 .9 反除也不是 13.5px。字重取 500: ui-kit.css:135-136 的
   .page-link 压根不声明字重(等于 Bootstrap 的 400), 但门户这几个是纯文字链接、没有 Bootstrap 的
   底衬, 400 会显得比后台虚 —— 500 是 ui-kit 里"未选中控件"的字重(ui-kit.css:41 的 .nav-item),
   取它才不算发明新值。 */
.pager a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: .22rem .6rem;      /* ui-kit.css:135 */
    border: 1px solid var(--border);    /* ui-kit.css:136 */
    border-radius: var(--r);            /* ui-kit.css:101 —— erp 的圆角三档里控件用 --r */
    background: var(--surface);         /* ui-kit.css:136 */
    color: var(--muted);                /* ui-kit.css:136 */
    font-size: 12.5px;          /* ui-kit.css:135 */
    font-weight: 500;           /* ui-kit.css:41 */
    transition: background-color .15s, border-color .15s, color .15s;
}

.pager a:hover { background: var(--hover); border-color: var(--border-strong); color: var(--text); }

/* 方向箭头用伪元素, 不动 JSP 里的文案(改文案要动 5 个页面, 不值得)。
   line-height:1 让 16px 的箭头不把行盒顶高: .pager a 是 align-items:center 的 flex, 行高最高的
   那个子项决定高度, 文字行盒 12.5×1.5=18.75px 已经比箭头的 16px 高, 所以箭头不参与撑高。 */
.pager a.prev::before { content: "\2039"; font-size: 16px; line-height: 1; }
.pager a.next::after { content: "\203A"; font-size: 16px; line-height: 1; }

/* ‼️ 复核修复(中危)"两个当前项一个最重一个最轻": 原来 .cur 只是一行灰字(color:var(--muted);
   font-size:12.5px), 连底色和边框都没有 —— 而 erp 的当前页是实心主色胶囊
   (ui-kit.css:137 `.pagination .page-item.active .page-link{background:var(--primary);
   border-color:var(--primary);color:#fff}`)。这是"选中态倒过来"的另一半, 和上面 .type-nav a.on
   一起改: 导航选中回到弱底(erp 的选中语言), 分页当前页升到实心(erp 的实心语义就是留给它的)。
   尺寸/字重和左右两个 a 完全一致(含那 1px 边框), 三个胶囊才会等高、基线不跳。
   等宽数字保留(ui-kit.css:198 的 font-variant-numeric), 防翻页时页码宽度抖动。 */
.pager .cur {
    display: inline-flex;
    align-items: center;
    padding: .22rem .6rem;              /* ui-kit.css:135, 同 .pager a */
    border: 1px solid var(--primary);   /* ui-kit.css:137 */
    border-radius: var(--r);            /* ui-kit.css:101 */
    background: var(--primary);         /* ui-kit.css:137 */
    color: #fff;                        /* ui-kit.css:137 */
    font-size: 12.5px;                  /* ui-kit.css:135 */
    font-weight: 500;                   /* 同 .pager a, 见上面注释 */
    font-variant-numeric: tabular-nums; /* ui-kit.css:198 */
}

/* ---------- 详情页 ---------- */
.detail { padding-top: 20px; }

/* 三块面板(head / intro / links)统一用 ui-kit 的卡片面: 白底 + 1px 描边 + 12px 圆角 + --sh-sm */
.detail .head,
.intro,
.links {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-sm);
    padding: 20px;
}

.detail .head { display: flex; gap: 24px; }

/* 文字列: 有意用 `> div` 而不是 .info —— detail.jsp 的 .head 里现在确实写着 <div class="info">(JSP 侧后加的),
   但 .info 不在类名契约里, 用结构选择器就不会把它变成第二个事实契约; 将来那个 div 改名也不用回来改样式。
   min-width:0 是关键: 不写它, 长片名/长主演会把 flex 项撑破导致海报被压扁。 */
.detail .head > div { flex: 1 1 auto; min-width: 0; }

.poster-big {
    width: 220px;
    flex: none;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: var(--r);
    border: 1px solid var(--border-2);
    background: var(--hover);
}

.detail h1 {
    margin: 0 0 6px;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: -.01em;
    line-height: 1.3;
}

.detail h1 .year { color: var(--muted); font-weight: 500; }

.detail .en { margin: 0 0 14px; color: var(--muted); font-size: 13.5px; }

/* 属性表: em 是固定宽标签列, flex 行比 inline-block 稳(值换行时不会跑到标签下面) */
.attrs { list-style: none; margin: 0; padding: 0; }

.attrs li {
    display: flex;
    gap: 10px;
    padding: 4px 0;
    font-size: 13.5px;
}

.attrs em {
    flex: none;
    width: 56px;
    font-style: normal;
    color: var(--muted);
    font-size: 13px;
}

/* ‼️ 预留规则, 当前不命中任何元素(复核点名的"死规则"之一, 有意保留): detail.jsp 的 <ul class="attrs">
   现在每个 <li> 都是 <em>标签</em> + fn:escapeXml 出来的纯文本, 没有 <a>。留着是为了"将来地区/类别/导演做成聚合页链接"时
   不用回来补样式 —— 但下一个人别以为它在生效。同类预留还有 .intro a / .site-footer a。 */
.attrs a { color: var(--primary); }

.intro,
.links { margin-top: 16px; }

.intro h2,
.links h2 {
    margin: 0 0 14px;
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -.01em;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
}

.intro p {
    margin: 0;
    color: var(--text);
    line-height: 1.75;
}

/* ‼️ 预留规则, 当前不命中(同 .attrs a): detail.jsp 的 <section class="intro"> 里是
   `<p>${fn:escapeXml(resource.intro)}</p>`, 转义过的纯文本, 不会有 <a>。将来简介支持富文本时才生效。 */
.intro a { color: var(--primary); }
.intro a:hover { text-decoration: underline; }

/* 条数 = mute pill, 和 .page-title .total 完全同一套: 尺寸/圆角/字号/字重/字距走上面的 pill 基配方
   (ui-kit.css:82), 这里只挑色。原来这条自己写了一遍 2px 9px 等六个值。 */
.links .cnt {
    background: var(--hover);
    color: var(--muted);
}

/* 窄屏时资源表在卡片内横滚, 不撑破页面(断点里给 .link-table 配 min-width)。
   ‼️ 复核修复(低危): 原注释断言"桌面无溢出, 这里不会出现滚动条" —— 说明列是唯一可伸缩列,
   一旦列内标记全都 nowrap, 表格 min-content 宽度就可能顶破容器, 桌面也会出滚动条。
   下面 .warn 已解除 nowrap 允许折行, 但这里改成不作断言: 桌面**通常**无溢出。
   本轮又堵掉一条: 操作列兜底分支里的裸 URL 原文(见下面 .link-table .ops:has(.warn))。
   已知遗留(未在本轮修): 本 section 内还包着 <h2>资源列表, 横滚时标题会跟着滑出视口 ——
   彻底修需要在 detail.jsp 里给 <table> 外面加一层滚动容器(新增契约类), 属于类名契约变更。 */
.links { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* ---------- 资源链接表 ---------- */
/* 逐字复刻 ui-kit.css:89-94 的 .uk-tbl 特征: 表头 12px/大写/字距 .03em/muted 色/
   --surface-2 底; 行线只用更浅的 --border-2; 最后一行去线; hover 整行染 --surface-2。 */
.link-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13.5px;
    font-variant-numeric: tabular-nums;
}

.link-table th {
    text-align: left;
    color: var(--muted);
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .03em;
    padding: 11px 14px;
    border-bottom: 1px solid var(--border-2);
    background: var(--surface-2);
}

.link-table td {
    padding: 12px 14px;
    border-bottom: 1px solid var(--border-2);
    transition: background-color .12s;   /* ui-kit.css:194 */
}

.link-table tbody tr:last-child td { border-bottom: 0; }
.link-table tbody tr:hover td { background: var(--surface-2); }

/* 列宽: 前三列定宽, 说明列(td.label, 本文件有意不给它写规则)吃掉剩余宽度 */
.link-table .type { width: 88px; color: var(--text); font-weight: 500; }
.link-table .res { width: 96px; color: var(--muted); }

/* nowrap 保留: 操作列正常只有"下载 + 复制链接"两个钮, 不许被挤成两行(它同时把这一列的
   min-content 撑到 ≈148px, 是桌面/移动两档下按钮不堆叠的唯一保证)。 */
.link-table .ops {
    width: 200px;
    white-space: nowrap;
}

/* ‼️ 追加修复(桌面横滚的最后一条路径, 本轮新发现): JSP 侧在本文件写完之后给下载链接加了协议白名单,
   并配了一条兜底分支 —— 协议不在白名单时不渲染成 <a>, 而是把 URL 原文当**裸文本节点**塞进这一格
   (按项目铁律"解析失败也保原文"), 那段文本没有类名可挂。
   上面那条 nowrap 撞上一条不可断的长 URL, 这一列的 min-content 宽度直接顶破容器, 下面 .links 的
   overflow-x:auto 在**桌面**也会出滚动条 —— 正是本文件 .links 处那条"桌面通常无溢出"想避免的情况;
   detail.jsp 那段的注释也已经明确把"给 .ops 补断行"这件事派给 CSS 侧。
   ‼️ 用 :has(.warn) 只钉住兜底分支那一行, 不动正常行 —— 兜底分支里跟着一个 <span class="warn">协议不支持</span>,
   是 .ops 内唯一会出现 .warn 的形态(正常行的 .warn 挂在说明列 td.label, 不在本列), 所以这条既解决了溢出, 又不会让正常行的
   两个钮失去 nowrap 保护。:has() 的渐进增强口径直接沿用 erp: ui-kit.css:140-141 的贴底 flex 就是
   "老浏览器不识别则整段忽略, 布局回到现状"—— 这里回到的现状是靠 .links 横滚兜住, 同样不破版。
   ‼️ 为什么配 overflow-wrap:anywhere 而不是 word-break:break-all —— break-all 会让这一格里**所有**
   文本(包括 .warn pill 的中文提示)在任意字符处断; anywhere 只在"不断就要溢出"时才断, 且会计入
   min-content 尺寸(这一点正是表格不再被撑破的关键, word-break:break-word 不计入所以在这里无效)。
   ‼️ 与 erp 的关系: ui-kit.css 没有对应条目 —— 后台表格是靠 .uk-tbl-scroll(ui-kit.css:94)外挂滚动
   容器兜溢出, 门户的等效物就是 .links 的 overflow-x:auto; 这里补的是"先别溢出"那一层, 不另立语言。
   特异性: :has() 取参数里最高的一项计入, 本条 0-3-0 压得住上面 0-2-0。 */
.link-table .ops:has(.warn) {
    white-space: normal;
    overflow-wrap: anywhere;
}

/* 上一条把整格放开折行后, 两个钮自己还得钉住(否则"复制链接"会被 anywhere 从中间断开)。
   0-3-0 压得住基类 .btn 的 0-1-0, 不需要 !important。 */
.link-table .ops .btn {
    white-space: nowrap;
}

/* 三个行内标记都走 pill 基配方(见文件上部"组件: 状态 pill", ui-kit.css:82), 这里只管定位外边距 +
   各自的语义色。
   ‼️ 复核修复(中危)"pill 碎成 5 套": 原来这条组规则自己写了 padding:1px 7px + border-radius:var(--r-sm)
   —— 是全站唯一用 6px 圆角冒充 pill 的地方, 而 .warn 还额外把字重压到 500, 一行里三个标记的高度、
   圆角、字重全不一样。现在三个都和卡片状态、标题计数共用同一套值。 */
.link-table .grp,
.link-table .pwd,
.link-table .warn {
    margin-left: 8px;
}

/* 只有这两个不许断行: .grp 是压制组名(BluRay-FRDS 这类, 断开就读不出是一个词),
   .pwd 是提取码(断行会让用户抄错)。
   ‼️ .warn 不在这个列表里(复核修复, 低危): 它的文案是整句("需电驴客户端, 有效性未验证", 12px 下约
   170px), 说明列是本表唯一可伸缩列, 一旦这句也 nowrap, 表格 min-content 宽度就会顶破容器,
   桌面也撑出横滚条。让它跟着单元格宽度自然折行, 所以这里不给它 nowrap(基配方也没有 nowrap)。 */
.link-table .grp,
.link-table .pwd {
    white-space: nowrap;
}

.link-table .grp { background: var(--hover); color: var(--muted); }
.link-table .pwd { background: var(--primary-weak); color: var(--primary); }
/* warn 语义变体 —— ui-kit.css:84 的 .uk-pill.warn 逐字。圆点由上部 pill 段的
   `.link-table .warn::before` 出(ui-kit.css:83): 这是风险状态, 按 erp 的语义该带点。
   折行时圆点会随 align-items:center 竖直居中在整块上(erp 的 pill 从不折行, 没有这个形态),
   属可接受观感; 圆点自身有 flex:none 所以不会被压成椭圆。 */
.link-table .warn { background: var(--warn-weak); color: var(--warn); }

/* ‼️ 追加(本轮新发现, 同样起因于 JSP 新增的白名单兜底分支): .warn 现在多了第二个挂载点 ——
   兜底分支把它放进了**操作列**, 而且是那一格的第一个元素(后面才是 URL 原文和"复制链接"钮)。
   上面那 8px 左外边距是给"跟在说明文字后面"的原场景写的(说明列 td.label 里的 .grp/.pwd/.warn), 落在一格的首元素上
   就成了一道没来由的缩进, 和同列其它行的按钮左沿对不齐。这里按挂载位置清零, 不动原场景。
   特异性 0-3-0 压得住上面那条 0-2-0; 语义色和 pill 基配方(ui-kit.css:82-84)都照旧继承, 不受影响。 */
.link-table .ops .warn { margin-left: 0; }

/* ---------- 按钮 ---------- */
/* 基类 = ui-kit.css:101 + :192-193 的值; padding/display/border 是 ui-kit 没给、
   原本由 Bootstrap 提供的部分 —— 前台不引 Bootstrap, 按 bs5 默认值补齐。 */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: .375rem .75rem;    /* bs5 .btn 默认值(ui-kit 不声明 padding) */
    line-height: 1.5;
    border: 1px solid transparent;
    border-radius: var(--r);    /* ui-kit.css:101 */
    font-family: inherit;
    font-size: 13.5px;          /* ui-kit.css:101 */
    font-weight: 600;           /* ui-kit.css:101 */
    cursor: pointer;
    transition: background-color .15s, border-color .15s, color .15s, box-shadow .15s, transform .06s;
    /* 默认态 = .btn-outline-primary(ui-kit.css:104): 下载是主动作, 描边不抢版面 */
    background: transparent;
    border-color: var(--primary);
    color: var(--primary);
}

.btn:hover { background: var(--primary); color: #fff; }        /* ui-kit.css:105 */
.btn:active { transform: translateY(.5px); }                    /* ui-kit.css:193 */

/* 在线播放 = 实心主色(唯一强调钮)。原来这里是橙色 #f0a020, 设计系统里没有这个色,
   门户不该自带第二套主色, 所以统一收到 --primary。
   ‼️ .btn-primary 当前不命中任何元素(复核点名的"死规则"之一, 有意保留): 7 个 JSP 里没人用它,
   detail.jsp 的"在线播放"用的是 class="btn play"。留着是因为它是类名契约里的可选项, 且和 ui-kit.css:102 同名 ——
   将来哪个页面写 class="btn btn-primary" 时不用回来补, 但别以为它现在在生效。 */
.btn.play,
.btn-primary {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
}

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

/* 复制链接 = 次要动作, 降级成 .btn-outline-secondary(ui-kit.css:109-110) */
.btn.copy {
    margin-left: 6px;
    border-color: var(--border);
    color: var(--muted);
    background: transparent;
}

.btn.copy:hover { background: var(--hover); border-color: var(--border-strong); color: var(--text); }

/* 表格内按钮收小一档 —— 同 ui-kit.css:128 只在表格里改 .btn-sm 的做法。
   ‼️ 复核修复(低危)"表内按钮比 erp 大一档且更重": 原来是 font-size:12.5px + padding:5px 11px, 字重
   还沿用基类的 600 —— 注释自称照 ui-kit.css:128, 但那条是
   `.table .btn-sm{font-size:12px;padding:.2rem .6rem;font-weight:500}`, 三个值一个都没对上。
   其中 600→500 和"密度"无关, 是纯字重错位: 表内按钮在 erp 里是**次要**控件, 字重比正文轻。
   三个值现在逐个对齐; 特异性 0-2-0 压得住基类 .btn 的 0-1-0, 不需要 !important。 */
.link-table .btn {
    font-size: 12px;            /* ui-kit.css:128 */
    padding: .2rem .6rem;       /* ui-kit.css:128 */
    font-weight: 500;           /* ui-kit.css:128 */
}

/* ---------- 播放页 ---------- */
/* 播放器外框跟卡片同一套圆角/描边; 里面是纯黑视频面, 所以 overflow:hidden 裁圆角。
   max-height 用 vh 是安全的: 本文件没有 zoom:.9, 视口单位不需要反除补偿。 */
.player-wrap {
    background: #000;
    border: 1px solid var(--border);
    border-radius: var(--r-lg);
    box-shadow: var(--sh-sm);
    overflow: hidden;
    margin-top: 4px;
}

.player-wrap video {
    display: block;
    width: 100%;
    max-height: 72vh;
    max-height: 72dvh;
    background: #000;
}

/* ‼️ 复核修复(中危, 同 .card 那条的同一机制): video 填满 .player-wrap 的 padding box,
   而 .player-wrap 有 overflow:hidden, 浏览器画在外侧的 UA 焦点环会被整圈裁掉 —— 键盘用户
   Tab 到播放器看不出焦点在哪。用负偏移把环画进内侧。 */
.player-wrap video:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -3px;
}

/* ‼️ 复核修复(低危): .player-tip 在 play.jsp 里是 <p>(现在有两个挂载点: 能播时的提示、协议不支持时的
   降级提示, 两个都是 <p class="player-tip">), 这里原来只写了 padding, UA 的 1em
   (13px)上下外边距还在 —— 上方实际间距是 13+14=27px 而不是写的 14px, 下方多出的 13px 又叠在
   .site-main 的 padding-bottom:32px 上, 使 play.jsp 到页脚 45px、其余 4 页 32px。清掉外边距,
   间距全部交给 padding 表达。 */
.player-tip {
    margin: 0;
    padding: 14px 0 0;
    color: var(--muted);
    font-size: 13px;
}

.player-tip a { color: var(--primary); }
.player-tip a:hover { text-decoration: underline; }
.player-tip strong { color: var(--text); }   /* JS 失败提示会塞 <strong>, 别是灰的 */

/* 404 / 空态里的返回链接要能被认出来是链接(404.jsp:33 的"回首页看看最新收录")。
   这里原来并挂的裸 .empty 已随上部空态段一起删掉(JSP 侧全仓无 class="empty")。 */
.empty-state a { color: var(--primary); }
.empty-state a:hover { text-decoration: underline; }

/* ---------- 页脚 ---------- */
/* flex:none = 吸底 flex 链的收尾项(见 body 处注释); 原来的 margin-top:40px 去掉了 ——
   吸底靠中间区 flex:1 吃剩余高度, 再加外边距反而会在短页面上多出一条缝。
   配色跟 erp 一致走浅色(白面 + 上边线 + muted 字), 不再用深色块。 */
.site-footer {
    flex: none;
    background: var(--surface);
    border-top: 1px solid var(--border);
    color: var(--muted);
    font-size: 13px;
    text-align: center;
    padding: 20px 0;
}

.site-footer p { margin: 0; }
/* ‼️ 预留规则, 当前不命中(同 .attrs a / .intro a): footer.jsp:8-12 里只有一个 <p>, 没有 <a>。
   将来加"关于/免责声明/联系"这类页脚链接时才生效。 */
.site-footer a { color: var(--muted); }
.site-footer a:hover { color: var(--primary); }

/* ============================================================
   移动端 <=640px
   原则: 顶栏换行不换高度写死、卡片列数降一档、详情页海报转竖排、宽表横滚。
   不做后台那套 [data-dense] 密度切换 —— 它只影响表格 padding, 门户用不上。
   ============================================================ */
@media (max-width: 640px) {
    .wrap { padding: 0 12px; }

    /* 顶栏换行: 站名 + 登录态一行, 搜索框整行放到第二行(order:3)。
       min-height 归 0(桌面那 58px 会把换行后的两行内容挤在一行高度里), 高度交给内容 + padding。 */
    /* ‼️ 复核修复(高危)"移动端顶栏贴边": 原来这里是 `padding:10px 0` 简写。header.jsp:25 是
       <div class="wrap header-inner"> —— 同一个元素同时命中本断点开头那条 .wrap{padding:0 12px}
       和本规则, 两条特异性都是 0-1-0 而本规则源序在后, 简写把 left/right 一并写成 0, 站名方块
       和"退出"直接贴死屏幕边缘(桌面正常: 桌面的 .header-inner 压根不声明 padding)。改成纵向
       长手, .wrap 的横向 12px 就能活下来 —— 观感对齐后台 ui-kit.css:261 移动端
       .uk-topbar{padding:0 14px}(横向留白在移动端保留)。
       铁律: 任何和 .wrap 挂在同一个元素上的私有类(还有 detail.jsp 的 <div class="wrap detail">)只能用
       padding-top/right/bottom/left 长手改内边距, 绝不能用 padding 简写。 */
    .header-inner {
        flex-wrap: wrap;
        min-height: 0;
        padding-top: 10px;
        padding-bottom: 10px;
        gap: 10px;
    }

    /* 站名字号 17→16px, 同后台移动端 ui-kit.css:262 的 .uk-topbar .title{font-size:16px}。
       ‼️ 这里原来还有一条 `.brand::before{width:24px;height:24px}` 把品牌方块再缩到 24px, 已删:
       后台移动断点(ui-kit.css:256-273)压根不碰 .uk-brand .logo, 30px 是全尺寸统一值; 再缩一档等于
       在移动端又造出第三套尺寸(桌面 30 / 移动 24), 而 30px 方块配 16px 站名的比例和 erp 的
       30px 配 17px 几乎一致, 换行后的顶栏也放得下。
       并挂的 `.header-inner > .logo` 兼容选择器同上部一起删(header.jsp:27 已是 class="brand")。 */
    .brand { order: 1; font-size: 16px; }

    .user-box { order: 2; }

    /* 整行 = flex-basis 100%, max-width 解除(桌面的 520px 上限在这里会留空) */
    .search-box { order: 3; flex: 1 1 100%; max-width: none; }

    .type-nav { gap: 6px; padding: 14px 0 2px; }
    .type-nav a { padding: 5px 13px; font-size: 13px; }

    .page-title { font-size: 18px; margin: 12px 0 14px; }

    .card-list { gap: 12px; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
    .card .meta { padding: 8px 10px 10px; }
    .card .title { font-size: 13px; }

    .pager { gap: 8px; padding: 22px 0 4px; }

    /* ‼️ 这里原来是 `.pager a{padding:7px 12px;font-size:13px}` —— 把桌面已经对齐 ui-kit.css:135 的
       字号又在移动端放大回 13px, 等于同一个控件两套字号。现在移动端**不动**视觉语言(字号/字重/
       圆角/配色一律沿用桌面的 erp 配方), 只把可点区域撑到 40px 高:
       后台是登录后台、只在桌面用(ui-kit.css:22-25 的 zoom 也只作用桌面), 没有触摸目标约束;
       门户要过 Lighthouse 的"点击目标过小"审计(文件头注释里为此专门放弃了 zoom:.9), 所以这一条
       是门户独有的补充, 而不是对 erp 的偏离 —— 撑的是触摸盒不是字。
       min-height 对 inline-flex + align-items:center 生效, 内容仍竖直居中。 */
    .pager a,
    .pager .cur { min-height: 40px; padding-left: .9rem; padding-right: .9rem; }

    .detail { padding-top: 14px; }
    .detail .head { flex-direction: column; gap: 16px; }
    .detail .head,
    .intro,
    .links { padding: 16px; }
    .poster-big { width: 150px; }
    .detail h1 { font-size: 20px; }
    .attrs em { width: 48px; }

    /* 四列表在小屏放不下: 给最小宽度让它在 .links 里横滚(上面已开 overflow-x:auto),
       比压成两行折行文字更好读; .ops 定宽解除, 按钮自己占位。 */
    .link-table { min-width: 480px; }
    .link-table th,
    .link-table td { padding: 10px 12px; }
    .link-table .ops { width: auto; }

    .player-wrap { border-radius: var(--r); }
    .player-wrap video { max-height: 56vh; max-height: 56dvh; }

    /* 并挂的裸 .empty 已随上部空态段一起删掉(JSP 侧全仓无 class="empty") */
    .empty-state { padding: 36px 12px; }
}
