/* av-picker 界面样式。纯手写，不引外部资源（容器内无需外网） */

:root {
  --bg: #14161a;
  --panel: #1c1f26;
  --panel-2: #232733;
  --line: #2e3440;
  --text: #e6e9ef;
  --dim: #98a1b3;
  --accent: #4f9cf9;
  --ok: #46c078;
  --warn: #e0a33e;
  --bad: #e05c5c;
  --radius: 8px;
}

* { box-sizing: border-box; }

/* ---------------------------------------------------------------- 滚动条 */
/* 默认滚动条又宽又丑，尤其和深色背景不搭。这里统一换成细窄的半透明样式。
   Firefox 用 scrollbar-width/scrollbar-color，Chromium 用 ::-webkit-scrollbar。 */
* { scrollbar-width: thin; scrollbar-color: var(--line) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 6px;
  /* 用透明边框 + background-clip 把滑块"缩窄"，看起来更精致 */
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: #4a5266; background-clip: content-box; }
::-webkit-scrollbar-corner { background: transparent; }

/* ---------------------------------------------------------------- 应用外壳 */
/* 整页用固定视口高度，页头不动，内容区自己滚 ——
   这样列表能撑满剩余高度（显示更多行），也不会出现
   "页面一条滚动条 + 列表一条滚动条"的双滚动条。 */
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.6 "PingFang SC", "Microsoft YaHei", "Noto Sans CJK SC", system-ui, sans-serif;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- 页头 */
header {
  display: flex; align-items: center; gap: 16px;
  padding: 12px 20px; background: var(--panel);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 10;
  flex-wrap: wrap;
}
header h1 { font-size: 16px; margin: 0; font-weight: 600; letter-spacing: .5px; }
header .spacer { flex: 1; }

nav { display: flex; gap: 4px; flex-wrap: wrap; }
nav button {
  background: transparent; border: 1px solid transparent; color: var(--dim);
  padding: 6px 14px; border-radius: var(--radius); cursor: pointer; font-size: 14px;
}
nav button:hover { color: var(--text); background: var(--panel-2); }
nav button.active { color: #fff; background: var(--accent); }
nav .badge {
  display: inline-block; margin-left: 6px; padding: 0 6px;
  background: var(--bad); color: #fff; border-radius: 9px; font-size: 11px;
}

main {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
  padding: 20px; width: 100%; max-width: 1500px; margin: 0 auto;
}

.page { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }

/* 单卡片页：卡片撑满剩余高度，只有内容区滚 */
.page > .panel {
  flex: 1 1 auto; min-height: 0; margin-bottom: 0;
  display: flex; flex-direction: column; overflow: hidden;
}
.page > .panel > .scroll {
  flex: 1 1 auto; min-height: 0; overflow-y: auto;
  /* 必须显式清掉 max-height。下面 .scroll 里那条 max-height:70vh 是老规则，
     flex 的优先级虽然更高、但管不到 max-height —— 不清掉的话列表会被
     卡在 70vh，面板再高也用不上，底部留一片空白。 */
  max-height: none;
}
/* 卡片里的固定部分不参与滚动 */
.page > .panel > h2,
.page > .panel > p,
.page > .panel > .row,
.page > .panel > .pager,
.page > .panel > .subtabs,
.page > .panel > .group-title,
.page > .subtabs,
.page > .panel > .bulkbar { flex: 0 0 auto; }

/* 多卡片页（如"状态"）：整页滚，卡片各自内容限高 */
.page.page-scroll { overflow-y: auto; }
.page.page-scroll > .panel { flex: 0 0 auto; overflow: visible; margin-bottom: 16px; }
.page.page-scroll > .panel > .scroll { max-height: 60vh; }

/* ---------------------------------------------------------------- 通用 */
.panel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 16px; margin-bottom: 16px;
}
.panel h2 { margin: 0 0 12px; font-size: 15px; font-weight: 600; }
.panel h3 { margin: 16px 0 8px; font-size: 13px; color: var(--dim); font-weight: 600; }

button.btn {
  background: var(--panel-2); color: var(--text); border: 1px solid var(--line);
  padding: 6px 14px; border-radius: var(--radius); cursor: pointer; font-size: 13px;
}
button.btn:hover { border-color: var(--accent); }
button.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
button.btn.danger { background: transparent; border-color: var(--bad); color: var(--bad); }
button.btn.danger:hover { background: var(--bad); color: #fff; }
button.btn:disabled { opacity: .45; cursor: not-allowed; }
button.btn.sm { padding: 3px 9px; font-size: 12px; }

input[type=text], input[type=password], select {
  background: var(--bg); border: 1px solid var(--line); color: var(--text);
  padding: 6px 10px; border-radius: var(--radius); font-size: 13px;
  font-family: inherit;
}
input:focus, select:focus { outline: none; border-color: var(--accent); }

.row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.muted { color: var(--dim); }
.small { font-size: 12px; }
.mono { font-family: ui-monospace, Consolas, monospace; }

/* ---------------------------------------------------------------- 表格 */
/* 用 fixed 布局：简介这类长文本不会把列宽撑爆，导致后面的列被挤出可视区。
   配合下面的 ellipsis 规则，超长内容截断显示，完整内容放 title 属性里。 */
table { width: 100%; border-collapse: collapse; font-size: 13px; table-layout: fixed; }
th, td {
  text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line);
  /* 纵向居中而不是顶对齐：简介格里有 28px 的 ✎ 按钮，行高会比纯文字格
     （番号/时间，约 21px）高一截，顶对齐时那两格的文字看着就"偏上"了。
     居中后每一格都对着行的中线，行里有没有按钮都齐。 */
  vertical-align: middle; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* 表头吸顶改为贴住滚动容器顶部（top:0）。
   原来写的 top:61px 是相对视口的偏移，放进 max-height 容器里后，
   行数一少表头就会压在数据行上面，看起来像"列表是空的"。 */
th {
  color: var(--dim); font-weight: 600; font-size: 12px;
  position: sticky; top: 0; background: var(--panel); z-index: 2;
  box-shadow: inset 0 -1px 0 var(--line);
}
tbody tr:hover { background: var(--panel-2); }
td.code { font-family: ui-monospace, Consolas, monospace; }
td.num { text-align: right; }
td.actions { text-align: center; }        /* 按钮居中，列宽收紧到刚好放下 */
a.iconbtn { text-decoration: none; }     /* 链接做成的按钮不要下划线 */
a.iconbtn:hover { text-decoration: none; }
/* 允许换行的单元格（如简介）加上这个类 */
td.wrap { white-space: normal; word-break: break-word; overflow: visible; }

/* 操作单元格里的按钮不能被裁掉。
   table-layout:fixed 在窗口变窄时会把所有列**等比压缩**，
   光把列写宽并不能保证按钮可见（会被 overflow:hidden 默默剪掉），
   所以这里放开裁剪，并禁止按钮换行/收缩。 */
td.actions, th.actions { overflow: visible; white-space: nowrap; }
td.actions .iconbtn, td.actions .btn { flex: 0 0 auto; }
td.nowrap { white-space: nowrap; }

.tag {
  display: inline-block; padding: 1px 7px; border-radius: 4px;
  font-size: 11px; border: 1px solid var(--line); color: var(--dim);
}
.tag.white { border-color: var(--ok); color: var(--ok); }
.tag.black { border-color: var(--bad); color: var(--bad); }
.tag.auto  { border-color: var(--accent); color: var(--accent); }
/* 蓝色 tag 的语义化名字（现在只有演员名右边的影片数用它；.tag.auto 是同一套配色，
   但"auto"挂在数字上读着别扭） */
.tag.blue  { border-color: var(--accent); color: var(--accent); }
.tag.warn  { border-color: var(--warn); color: var(--warn); }

.empty { padding: 40px; text-align: center; color: var(--dim); }

/* ---------------------------------------------------------------- 进度条 */
.bar { background: var(--bg); border-radius: 4px; height: 6px; overflow: hidden; min-width: 80px; }
.bar > i { display: block; height: 100%; background: var(--accent); transition: width .4s; }
.bar.done > i { background: var(--ok); }
.bar.err > i { background: var(--bad); }

/* ---------------------------------------------------------------- 登录 */
#login {
  position: fixed; inset: 0; background: var(--bg);
  display: flex; align-items: center; justify-content: center; z-index: 100;
}
#login .box { background: var(--panel); padding: 32px; border-radius: 12px;
              border: 1px solid var(--line); width: 320px; }
#login h1 { margin: 0 0 20px; font-size: 18px; text-align: center; }
#login input { width: 100%; margin-bottom: 14px; padding: 10px; }
#login button { width: 100%; padding: 10px; }
#login .remember {
  display: flex; align-items: center; gap: 8px;
  margin: -6px 0 14px; font-size: 13px; color: var(--dim); cursor: pointer;
  user-select: none;
}
#login .remember input { width: 16px; height: 16px; margin: 0; }

/* ---------------------------------------------------------------- 提示 */
#toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: var(--panel-2); border: 1px solid var(--line); color: var(--text);
  padding: 12px 20px; border-radius: var(--radius); display: none; z-index: 200;
  max-width: 80vw; box-shadow: 0 6px 24px rgba(0,0,0,.5);
}
#toast.show { display: block; }
#toast.err { border-color: var(--bad); }
#toast.ok { border-color: var(--ok); }

.hidden { display: none !important; }
/* 兜底样式：给那些不在"面板撑满"结构里的 .scroll 用
   （比如弹窗、状态页里的卡片）。撑满结构的会被上面
   .page > .panel > .scroll 覆盖成 max-height:none。 */
.scroll { max-height: 70vh; overflow: auto; position: relative; }

/* 列表下方的批量操作条 */
.bulkbar {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 10px 0; border-bottom: 1px solid var(--line); margin-bottom: 10px;
}
.bulkbar .spacer { flex: 1; }

/* 分组标题（下载页按状态分组用） */
.group-title {
  display: flex; align-items: center; gap: 8px;
  margin: 18px 0 8px; font-size: 14px; font-weight: 600;
}
.group-title .count { color: var(--dim); font-weight: 400; font-size: 12px; }

/* 演员别名标签组 */
.aliases { display: flex; flex-wrap: wrap; gap: 4px; }
.alias-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 1px 6px; border: 1px solid var(--line); border-radius: 4px;
  font-size: 11px; color: var(--dim);
}
/* 别名列现在只列别名，正式名称不再做成绿色的"正式"标签（左边那列就是它），
   所以 .alias-chip.main / .chip-tag 两条样式一并删掉。 */
.alias-chip button {
  background: none; border: none; color: inherit; cursor: pointer;
  padding: 0 2px; font-size: 12px; line-height: 1;
}
.alias-chip button:hover { color: var(--accent); }

/* ---------------------------------------------------------------- 图形按钮 */
/* 列表里的操作一律用图标，鼠标移上去才显示提示（title 属性） */
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; padding: 0; margin: 0 2px;
  background: var(--panel-2); color: var(--dim);
  border: 1px solid var(--line); border-radius: 6px;
  cursor: pointer; font-size: 15px; line-height: 1;
  transition: all .12s;
}
.iconbtn:hover { color: #fff; transform: translateY(-1px); }
.iconbtn.ok:hover      { background: var(--ok);     border-color: var(--ok); }
.iconbtn.no:hover      { background: var(--bad);    border-color: var(--bad); }
.iconbtn.assign:hover  { background: var(--accent); border-color: var(--accent); }
.iconbtn:disabled      { opacity: .4; cursor: not-allowed; transform: none; }
.iconbtn.busy          { opacity: .5; pointer-events: none; }

/* 行正在被处理时的淡出效果，让"操作完就消失"看起来不那么突兀 */
tr.row-gone { opacity: 0; transition: opacity .25s; }

/* ---------------------------------------------------------------- 模态框 */
.modal {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(0, 0, 0, .6);
  display: flex; align-items: center; justify-content: center;
}
.modal-box {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; padding: 18px; width: min(560px, 92vw);
  max-height: 82vh; display: flex; flex-direction: column; gap: 10px;
}
.modal-head { display: flex; align-items: center; gap: 10px; }
/* 标题（影视库播放窗里就是片名，能很长）**必须能缩**：flex 默认 min-width:auto，
   长标题会把右边的按钮挤到只剩一个字宽，按钮里的"关闭"就竖排成两行了
   —— 用户实测就是这么撞上的。所以标题负责省略号，按钮负责不缩。 */
.modal-head h3 {
  margin: 0; font-size: 15px;
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.modal-head .btn, .modal-head .iconbtn { flex: 0 0 auto; white-space: nowrap; }
.modal-box input[type=text] { width: 100%; padding: 8px 10px; }
.modal-list { overflow: auto; max-height: 52vh; border: 1px solid var(--line); border-radius: 6px; }
.modal-list .pick-row {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; cursor: pointer; border-bottom: 1px solid var(--line);
}
.modal-list .pick-row:last-child { border-bottom: none; }
.modal-list .pick-row:hover { background: var(--panel-2); }
.modal-list .pick-row .nm { flex: 1; }
.modal-list .pick-row .al { color: var(--dim); font-size: 11px; }

/* 弹窗里"把当前这个名字直接拉进白/黑名单"的快捷条。
   它和下面的列表是两件事：这条只改名单归属，下面的列表是"归并到某个人名下"。 */
.modal-quick {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; margin-top: 8px;
  border: 1px dashed var(--line); border-radius: var(--radius);
}
.modal-quick .btn.qw:hover { background: var(--ok); border-color: var(--ok); color: #fff; }
.modal-quick .btn.qb:hover { background: var(--bad); border-color: var(--bad); color: #fff; }

/* 播放器（影视库点 ▶ 出来的那个）：比选择框宽得多，画面按比例铺满 */
.player-box { width: min(1100px, 94vw); max-height: 92vh; }
#playerVideo {
  width: 100%; max-height: 74vh; background: #000;
  border-radius: 6px; display: block;
}
.player-box p { margin: 0; }

/* ---------------------------------------------------------------- 分页 */
.pager { display: flex; align-items: center; gap: 8px; justify-content: center; padding: 12px 0; }
.pager .info { color: var(--dim); font-size: 12px; }

/* 搜索框 + 右侧按钮同排。
   移动端有条通用规则把 .row 里的文本框撑成 100% 宽，那会把按钮挤到下一行，
   这里显式覆盖掉。 */
.filter-row { flex-wrap: nowrap; }
.filter-row > input[type=text] { flex: 1 1 auto; min-width: 0; width: auto; }
.filter-row > .btn { flex: 0 0 auto; margin-left: auto; }

/* 警示条（如"定时任务没在运行"） */
.warnbar {
  padding: 10px 12px; margin: 8px 0 12px;
  border: 1px solid var(--warn); border-radius: var(--radius);
  background: rgba(224, 163, 62, .1);
  color: var(--warn); font-size: 13px; line-height: 1.6;
  white-space: normal; overflow-wrap: anywhere;
}

/* 空状态里的操作提示 */
.hint-row { color: var(--dim); font-size: 12px; padding: 4px 0; }

/* 共演片：演员列里每位演员占一行，各带自己的"指定"按钮。
 *
 * 这里的高度要和普通单元格的文字行高对齐，否则演员名会比旁边的"xx GB"
 * 低几个像素。踩过的坑：给 .actor-line 设了 min-height:26px，而按钮是 28px、
 * 文字行高只有约 21px，align-items:center 把文字在 26px 里居中，
 * 结果就比相邻单元格矮了约 3px。现在不设 min-height，并把按钮缩到 20px，
 * 让整行高度≈文字行高。
 */
.actor-line {
  display: flex; align-items: center; gap: 4px;
  white-space: nowrap; line-height: 1.6;
}
.actor-line + .actor-line { margin-top: 2px; }
.actor-line .iconbtn { width: 20px; height: 20px; font-size: 12px; }

/* 排队中那张卡可以拖动排序 —— 但**只有行首那个手柄**能发起拖动，
   整行都能拖的话随手一点就误触了。鼠标落在手柄上才显示抓手。 */
.grip-cell { padding-right: 0; overflow: visible; }
.drag-handle {
  display: inline-block; cursor: grab; user-select: none;
  color: var(--dim); font-size: 15px; line-height: 1; padding: 2px 4px;
  border-radius: 4px;
}
.drag-handle:hover { color: var(--text); background: var(--panel-2); }
[data-tab-panel="queued"] tbody tr.dragging { opacity: .45; }
[data-tab-panel="queued"] tbody tr.dragging .drag-handle { cursor: grabbing; }
/* "总速度"小药丸：未选中时用绿色（在深色面板上清楚），
   **选中时改成白字** —— 选中的标签是蓝底，绿字在上面几乎看不清 */
.subtabs button .cnt.spd { margin-left: 4px; color: var(--ok); }
.subtabs button.active .cnt.spd { color: #fff; font-weight: 600; }

/* 下载页里"一个种子多部片"的任务：把每部片列成一行，各带自己的取消按钮。
   一行 = 一个 aria2 任务，光看任务级标题只会知道其中一部。 */
.film-head { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; }
.film-list { display: flex; flex-direction: column; gap: 2px; }
.film-line { display: flex; align-items: center; gap: 6px; }
.film-line .code-mini {
  flex: 0 0 auto; font-size: 11px; color: var(--dim);
  font-family: ui-monospace, Consolas, monospace;
}
.film-line .title-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
                         white-space: nowrap; }
.film-line .iconbtn { width: 20px; height: 20px; font-size: 12px; }
.film-line .actor-mini {
  flex: 0 1 auto; max-width: 34%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--dim); font-size: 11.5px;
}
/* 状态格：文字靠左、按钮贴右。
   flex 必须加在内层 div 上 —— 直接给 <td> 设 display:flex 会让它脱离表格布局
   （和简介格同样的道理）。不加这层的话按钮只是跟在文字后面，
   剩下的宽度全空在单元格右边，看着就是"删除按钮后面空一大片"。 */
.status-wrap { display: flex; align-items: center; gap: 8px; }
.status-wrap > span { margin-right: auto; }
.status-wrap .iconbtn {
  flex: 0 0 auto; width: 24px; height: 24px;
  font-size: 13px; margin: 0; vertical-align: middle;
}
@media (max-width: 700px) {
  /* 触屏上每部片自己的取消按钮做大一点（20px 手指点不准） */
  .film-line .iconbtn { width: 30px; height: 30px; font-size: 14px; }
  .film-line .title-text { white-space: normal; }
}

/* 演员名可以点（手输改名 / 给"未知"补一个名字）。
   用虚线下划线提示"这里能改"，不然没人知道能点。 */
.actor-name { cursor: pointer; border-bottom: 1px dotted var(--dim); }
.actor-name:hover { color: var(--accent); border-bottom-color: var(--accent); }
/* 演员列不能被裁掉，否则"共 N 位"和按钮会看不见 */
td.actor-cell { overflow: visible; white-space: normal; }

/* 多选弹窗里的勾选行 */
.pick-row input[type=checkbox] { width: 15px; height: 15px; flex: 0 0 auto; }

/* 番号单元格：番号 + 复制按钮（只在待确认列表）。
   跟简介单元格同样的道理 —— flex 要加在内层 div 上，
   直接加在 <td> 上会让它脱离 table-cell，表格布局会塌。 */
.code-wrap { display: flex; align-items: center; gap: 4px; }
.code-wrap .code-text {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.code-wrap .iconbtn { flex: 0 0 auto; width: 22px; height: 22px;
                      padding: 0; opacity: 0; transition: opacity .12s; }
.code-wrap .iconbtn svg { display: block; }
tr:hover .code-wrap .iconbtn { opacity: 1; }
/* 触屏没有 hover，按钮常显 */
@media (hover: none) {
  .code-wrap .iconbtn { opacity: .7; }
}

/* 简介单元格：文字 + 改写按钮。
   注意 flex 要加在**内层 div** 上，直接加在 <td> 上会破坏表格布局。 */
td.title-cell { overflow: visible; }
.title-wrap { display: flex; align-items: center; gap: 6px; }
.title-wrap .title-text {
  flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.title-wrap .iconbtn { flex: 0 0 auto; opacity: .55; }
tr:hover .title-wrap .iconbtn { opacity: 1; }

/* ==========================================================================
   移动端适配
   目标机型：华为 Mate 40 这类 6.5 寸屏（1080×2376，CSS 视口宽约 390~430px）。
   不考虑更小的小屏机。

   核心思路：表格在 400px 宽度下横向滚动非常难用，所以在窄屏把每一行
   转成一张卡片 —— 列名用 td 的 data-label 以 ::before 显示。
   ========================================================================== */
@media (max-width: 700px) {
  /* ---- 整体留白收紧 ---- */
  main { padding: 10px; }
  body { font-size: 13.5px; }
  .panel { padding: 12px; margin-bottom: 12px; border-radius: 10px; }
  .panel h2 { font-size: 14px; margin-bottom: 8px; }
  /* 注意：这里**不能**把 .scroll 改成 overflow:visible ——
     新的外壳布局靠它做唯一的滚动容器，改成 visible 会导致整页又滚起来，
     卡片头也跟着跑。宽度自适应交给上面的 .page > .panel > .scroll。 */
  .page.page-scroll > .panel > .scroll { max-height: 60vh; }

  /* ---- 页头：标题一行，导航单独一行横向滚动 ---- */
  header {
    padding: 8px 12px; gap: 6px; position: sticky; top: 0;
  }
  header h1 { font-size: 15px; }
  header .spacer { display: none; }
  nav {
    order: 3; width: 100%; overflow-x: auto; flex-wrap: nowrap;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding-bottom: 2px;
  }
  nav::-webkit-scrollbar { display: none; }
  nav button { flex: 0 0 auto; padding: 6px 12px; font-size: 13px; }
  /* 顶部那几个操作按钮靠右排一行 */
  header > .btn { flex: 0 0 auto; }

  /* ---- 表格转卡片 ---- */
  table, tbody, tr, td { display: block; width: auto !important; }
  colgroup, thead { display: none; }        /* 列宽定义和表头都不需要了 */
  tbody tr {
    border: 1px solid var(--line); border-radius: 10px;
    background: var(--panel-2); padding: 8px 10px; margin-bottom: 8px;
  }
  tbody tr:hover { background: var(--panel-2); }
  td {
    border: none; padding: 3px 0; white-space: normal;
    overflow: visible; text-overflow: clip; text-align: left;
  }
  td.num { text-align: left; }
  /* 列名标签：data-label 为空（如操作列、链接列）就不显示 */
  td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    display: inline-block; min-width: 46px;
    color: var(--dim); font-size: 12px; vertical-align: top;
  }
  /* 简介是卡片里最长的一段，给它整行显示 */
  td.title-cell { margin-top: 2px; }
  td.title-cell .title-wrap { gap: 8px; }
  td.title-cell .title-text { white-space: normal; overflow: visible; }
  .title-wrap .iconbtn { opacity: 1; }      /* 触屏没有 hover，别藏 */
  /* 操作按钮并排一行。
     卡片布局默认把每个 td 变成独占一行的 block，
     这里改回 inline-block，✓ ✕ 和链接就会挨在一起而不是各占一行。 */
  td.actions {
    display: inline-block !important;
    width: auto !important;
    text-align: left; white-space: nowrap;
    margin: 8px 6px 0 0; padding: 0;
    border-top: none;
  }
  /* 空的操作格别占位：下载页的取消按钮已经挪进"状态"格里，
     这一格空着却还带着 8px 上边距和行高，会把卡片白白撑高一行 */
  td.actions:empty { display: none !important; }
  /* 下载页的"状态"格：手机上也是文字靠左、按钮靠右（窄屏按钮做大些好点） */
  .status-wrap .iconbtn { width: 30px; height: 30px; font-size: 15px; }
  /* 链接也做成方按钮，和 ✓ ✕ 视觉一致。
     只改尺寸 —— 底色/边框全部沿用 .iconbtn 基类，
     之前多写了一句 background:var(--panel)，和 ✓✕ 的 --panel-2 不一样，
     结果链接按钮底色明显更深。 */
  td.actions a.iconbtn {
    width: 34px; height: 34px; font-size: 16px;
  }
  /* 窄屏下 td 是 overflow:visible，长串（JSON、路径）必须能断行，
     否则会横向撑破卡片 */
  td, td.mono, .mono { overflow-wrap: anywhere; word-break: break-word; }
  td.actions .iconbtn { width: 34px; height: 34px; font-size: 16px; }
  td.actions .btn { padding: 7px 12px; font-size: 13px; }
  .actor-line .iconbtn { width: 30px; height: 30px; font-size: 14px; }
  .actor-line { gap: 8px; }
  .alias-chip button { padding: 0 6px; font-size: 14px; }   /* 触屏好点 */

  /* ---- 弹窗占满宽度，输入框和选项做大 ---- */
  .modal-box { width: 94vw; max-height: 88vh; padding: 14px; }
  .modal-list { max-height: 58vh; }
  .pick-row { padding: 12px 10px; }
  .pick-row input[type=checkbox] { width: 20px; height: 20px; }
  .modal-box input[type=text] { padding: 10px; font-size: 15px; }

  /* ---- 表单控件做大，避免手机浏览器自动放大 ---- */
  input[type=text], input[type=password], select, input[type=date] {
    font-size: 16px; padding: 9px 10px; width: 100%;
  }
  .row { gap: 8px; }
  .row > input[type=text], .row > select { flex: 1 1 100%; }
  /* 例外：搜索框和它的按钮要留在同一行 */
  .filter-row > input[type=text] { flex: 1 1 auto; min-width: 0; }

  /* ---- 分页换行居中 ---- */
  .pager { flex-wrap: wrap; gap: 6px; }
  .pager .info { flex: 1 1 100%; text-align: center; }

  /* ---- 提示条贴底整宽 ---- */
  #toast { left: 10px; right: 10px; transform: none; max-width: none; bottom: 12px; }

  /* 登录框 */
  #login .box { width: 88vw; padding: 24px; }

  #toTop { right: 14px; bottom: 16px; width: 46px; height: 46px; font-size: 21px; }
}

/* ==========================================================================
   切换式卡片：把原来上下堆叠的多个卡片改成标签切换。
   手机上堆三四个卡片要滚很久才能看到第二个，切换就一步到位。
   ========================================================================== */
.subtabs {
  display: flex; gap: 6px; flex-wrap: wrap;
  flex: 0 0 auto; margin-bottom: 10px;
}
.subtabs button {
  flex: 1 1 auto; padding: 8px 12px; cursor: pointer;
  background: var(--panel); color: var(--dim);
  border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 13px; font-family: inherit; white-space: nowrap;
}
.subtabs button:hover { color: var(--text); }
.subtabs button.active { background: var(--accent); border-color: var(--accent); color: #fff; }
.subtabs button .cnt {
  display: inline-block; margin-left: 5px; padding: 0 6px;
  border-radius: 9px; background: rgba(255, 255, 255, .15); font-size: 11px;
}
.subtabs button.active .cnt { background: rgba(255, 255, 255, .3); }

/* 回到顶部：右下角浮动按钮 */
#toTop {
  position: fixed; right: 16px; bottom: 20px; z-index: 90;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--accent); color: #fff; border: none;
  font-size: 20px; line-height: 1; cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .45);
  opacity: .9;
}
#toTop:hover { opacity: 1; }
#toTop:active { transform: scale(.94); }

/* 横屏或小平板：保留表格，但收紧留白 */
@media (min-width: 701px) and (max-width: 1000px) {
  main { padding: 14px; }
  .panel { padding: 14px; }
}

/* 滚动加载到底部的提示 */
.more-hint {
  padding: 14px 0; text-align: center;
  color: var(--dim); font-size: 12px;
}

/* 影视库：从归档条目跳过来时，把"就是这一条"标出来（滚到眼前 + 左侧一条亮边）。
   高亮不随时间淡出 —— 用户可能先看列表里的别的东西再回头找它。 */
tr.hl > td { background: rgba(79, 156, 249, .13); }
tr.hl > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* 改路径/文件名弹窗 */
#rename .modal-box label { margin-bottom: -6px; }
#renamePreview {
  color: var(--dim); word-break: break-all;
  background: var(--panel-2); border-radius: 6px; padding: 6px 8px; margin: 0;
}
#renameErr:empty { display: none; }
#renameErr { color: var(--bad); margin: 0; }

/* ---------------------------------------------------------------- 番号搜索 */
/* 页头那个搜索框（在「立即抓取」左边）：放大镜**放在输入框里面靠右**，
   不占额外宽度 —— 页头本来就挤，多一个 28px 的按钮能把导航挤到第二行。 */
.code-search { position: relative; display: inline-flex; align-items: center; }
.code-search input[type=text] {
  width: 210px; font-size: 13px;
  padding: 4px 32px 4px 9px;            /* 右边留出放大镜的位置 */
}
.code-search .iconbtn {
  position: absolute; right: 3px; top: 50%;
  width: 22px; height: 22px; margin: 0;
  background: transparent; border-color: transparent;
  /* 这里必须把 .iconbtn:hover 那个 translateY(-1px) 盖掉，
     否则鼠标一划过按钮就跳一下、不居中了 */
  transform: translateY(-50%);
}
.code-search .iconbtn:hover {
  background: var(--panel-2); border-color: var(--line);
  transform: translateY(-50%);
}

/* 结果列表：一行一个源，源的名字做成 tag 放在最前面（用户要的），
   下面是这一路查到的条目。几路并行查，查完一路填一路 */
.search-list { display: flex; flex-direction: column; gap: 8px; margin-top: 4px; }
.search-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 10px 12px; background: var(--panel-2);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.search-row > .tag { flex: 0 0 auto; min-width: 72px; text-align: center; }
.search-row .hit-list {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: 6px;
}
.search-hit {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px;
  min-width: 0;
}
.search-hit .title-text { flex: 1 1 240px; min-width: 0; }
.search-hit .mono { word-break: break-all; }

@media (max-width: 700px) {
  .code-search { flex: 1 1 100%; }
  .code-search input[type=text] { width: auto; flex: 1 1 auto; }
}

/* 搜索结果里每条的复制按钮：贴着这一行的右边 */
.search-hit .copyHit { flex: 0 0 auto; margin-left: auto; }

/* 演员名 + 影片数 tag：tag **靠右**（名字撑开、tag 贴右边沿），
   名字太长时截断，tag 不参与收缩、始终看得见 */
.actor-name-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.actor-name-row b { flex: 1 1 auto; min-width: 0;
                    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.actor-name-row .tag { flex: 0 0 auto; }
