/* ==========================================================================
   爆枪突击字幕库 — 全站样式
   设计原则：浅色默认、无渐变、无装饰性光晕，尽量简洁。
   改配色只需改下面这两个变量块。
   ========================================================================== */

/* 浅色（默认） */
:root {
  --bg: #ffffff;
  --bg-soft: #fafbfc;
  --surface: #ffffff;
  --surface-2: #f4f5f7;

  --border: #e4e7ec;
  --border-strong: #d0d5dd;

  --text: #101828;
  --text-muted: #667085;
  --text-dim: #98a2b3;

  --accent: #2563eb;
  --accent-soft: #eff4ff;
  --ok: #059669;
  --ok-soft: #ecfdf5;
  --warn: #b45309;
  --warn-soft: #fffbeb;
  --danger: #b42318;
  --danger-soft: #fef3f2;

  --code-bg: #f4f5f7;

  --radius: 10px;
  --radius-sm: 7px;

  --maxw: 1000px;
  --header-h: 58px;

  --font: system-ui, -apple-system, "Segoe UI", "Microsoft YaHei", "PingFang SC",
    "Hiragino Sans GB", sans-serif;
  --font-mono: ui-monospace, "Cascadia Code", Consolas, "Courier New", monospace;
}

/* 深色（用户手动切换后） */
html[data-theme="dark"] {
  --bg: #101216;
  --bg-soft: #14171c;
  --surface: #161a20;
  --surface-2: #1e232b;

  --border: #262c36;
  --border-strong: #39414e;

  --text: #e6e8ec;
  --text-muted: #98a1af;
  --text-dim: #6c7684;

  --accent: #5b91f5;
  --accent-soft: #172236;
  --ok: #34d399;
  --ok-soft: #10281f;
  --warn: #fbbf24;
  --warn-soft: #2a2210;
  --danger: #f97066;
  --danger-soft: #2d1513;

  --code-bg: #1b1f27;
}

/* 切换主题时，让全站元素用同一条过渡曲线一起变色。
   不加这段的话：本身就带 transition 的元素（.btn / .nav a / .icon-btn）在慢慢渐变，
   而 body、.file-row 这些没有 transition 的会瞬间跳变 ——
   切换的那一刹那画面是「有的还在浅色、有的已经黑了」的参差不齐。
   只在切换的 220ms 内挂上 html.theme-anim，所以不影响平时的 hover 动画。

   类名故意写两遍（html.theme-anim.theme-anim）把特异性提到 (0,2,1)。
   实测教训：只写一遍是 (0,1,1)，会和 .nav a / .hero-search input 这类
   「类+标签」选择器打平；它们在文件后面，按顺序反而盖住这里，
   结果那些元素仍旧瞬间跳变（测出来 input 的背景 60ms 就已经是终值）。

   故意不用 !important：文件末尾那条
   「prefers-reduced-motion 时 * { transition: none !important }」还要能生效。 */
html.theme-anim.theme-anim *,
html.theme-anim.theme-anim *::before,
html.theme-anim.theme-anim *::after {
  transition: background-color 0.18s ease, border-color 0.18s ease,
    color 0.18s ease, box-shadow 0.18s ease, fill 0.18s ease, stroke 0.18s ease;
}

* { box-sizing: border-box; }

/* hidden 属性必须能盖过我们自己写的 display。
   浏览器默认的 [hidden] { display: none } 特异性太低，会被 .file-actions{display:flex}
   这类规则覆盖 —— 结果「隐藏」的元素反而一直显示（裁剪框、上传按钮都踩过这个坑）。 */
[hidden] { display: none !important; }

/* 始终预留滚动条的位置。
   为什么：首页 / 关于的内容长，会出现竖向滚动条；字幕库 / 游戏内容短，没有。
   不预留的话，有滚动条的页面可用宽度少 15px，四个页面的顶栏会左右差一截，
   来回切换时能明显看到整条顶栏在跳。
   ★ 实测只用 scrollbar-gutter: stable 在这套页面上不生效（没有滚动条时
   clientWidth 仍等于 innerWidth），所以用 overflow-y: scroll 兜底 ——
   它保证根元素永远是一个滚动容器，槽位就一直在。 */
html {
  overflow-y: scroll;
  scrollbar-gutter: stable;
  /* 移动端点链接时系统会盖一层蓝色高亮块（Android Chrome / iOS Safari 都是），
     形状方、颜色跟站内完全不搭 —— 关掉，交互反馈交给 CSS 自己的 :hover/:active。 */
  -webkit-tap-highlight-color: transparent;
  /* 给根元素也铺上主题底色。平时看不出区别（body 已经铺了一层），但
     iOS 橡皮筋回弹、页面切换的空白帧里露出来的是 html 的背景 ——
     不设的话那里永远是白的，深色模式下会闪一下白。 */
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
}

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

/* 手机端点完链接，焦点会留在那个元素上，Chrome 就给它画一圈系统蓝框。
   只在「不是键盘操作」时去掉它 —— 键盘 Tab 出来的焦点（:focus-visible）
   必须保留，否则用键盘的人完全看不到自己在哪。 */
a:focus:not(:focus-visible),
button:focus:not(:focus-visible),
input:focus:not(:focus-visible),
select:focus:not(:focus-visible),
[tabindex]:focus:not(:focus-visible) {
  outline: none;
}

/* ★ <a> 和 <button> 不一样：手机点链接不算 :focus-visible（上面那条能挡住），
   但点 <button> Chrome 会判定成 :focus-visible —— 因为按钮被当作「操作」。
   于是「上一页 / 下一页」这类按钮点完，蓝色焦点框就一直留在上面。
   触摸屏本来没有「键盘焦点」这回事，粗指针设备上整类元素直接去掉焦点框；
   带鼠标的设备（hover: hover）不受影响，Tab 键照常能看见焦点。
   （2026-10-18 用户反馈「点下一页蓝色常驻」） */
@media (hover: none) {
  a:focus,
  button:focus,
  input:focus,
  select:focus,
  textarea:focus,
  [tabindex]:focus {
    outline: none;
  }
}

img { max-width: 100%; display: block; }

/* 去掉浏览器给 <input type="search"> 画的原生清除按钮。
   不去掉的话，它会和字幕库自己那个「×」同时出现，看起来像两个删除号。
   注意：必须分开写 —— 如果在选择器列表里塞进引擎不认识的伪元素（比如 ::-ms-clear），
   整条规则会被直接丢弃，等于没写。 */
input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}
input[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
  appearance: none;
}

code, kbd { font-family: var(--font-mono); font-size: 0.88em; }
code {
  background: var(--code-bg);
  padding: 1px 5px;
  border-radius: 4px;
}
kbd {
  background: var(--code-bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0 5px;
  font-size: 0.85em;
}

.container {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 20px;
}

/* ============================ 顶部导航 ============================ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--header-h);
  display: flex;
  align-items: center;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}

.site-header .container {
  display: flex;
  align-items: center;
  gap: 16px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  font-size: 15.5px;
  color: var(--text);
  white-space: nowrap;
}
.brand:hover { text-decoration: none; }

.brand-logo {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
  border: 1px solid var(--border);
}

.nav {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
  --nav-h: 34px;      /* 导航里所有控件统一个高度，见下面 #siteNav > a 那段 */
}

.nav a {
  padding: 6px 12px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: 14.5px;
  transition: background 0.14s, color 0.14s;
  white-space: nowrap;
}
.nav a.active { color: var(--accent); background: var(--accent-soft); font-weight: 500; }

/* ★ 导航里三类控件（链接 / 语言下拉 / 主题按钮）必须**同高**
   —— 原来链接是 6px 内边距 + 14.5px 字（实测 35.9px），语言按钮 29.5px，
   主题按钮 28px，于是「当前页」那块高亮底色比旁边的按钮高一圈，
   看着就是没对齐（用户 2026-10-18 两次反馈「应该对齐」）。 */
@media (min-width: 721px) {
  #siteNav > a {
    display: inline-flex;
    align-items: center;
    height: var(--nav-h);
    padding: 0 12px;
  }
  #siteNav > .dropdown > .lang-toggle,
  #siteNav > #themeBtn {
    height: var(--nav-h);
    min-height: var(--nav-h);
  }
  /* 语言下拉和主题按钮之间留一点缝：两个都是**带边框的按钮**，
     只靠 .nav 的 2px gap 会挨在一起像同一个控件被切成两半
     （用户 2026-10-18 反馈「语言和颜色切换贴太紧了」）。
     只加这一处 —— 链接之间仍然紧凑，不会又变成「整排都被撑开」。 */
  #siteNav > #themeBtn { margin-left: 8px; }
}

/* 「关于」和主题按钮之间留出明显空隙 —— 原来只靠 .nav 的 2px gap，
   两个东西挨在一起，看着像同一个控件（2026-10-18 用户指出）。
   现在中间插了语言下拉，空隙交给 .nav 的 gap 统一控制；
   再叠 margin 会在语言按钮前后各多出一截空白（用户 2026-10-18 反馈「电脑端有空格」）。
   ↑ 上面媒体查询里的 margin-left: 8px 是例外：只拉开「语言 ↔ 主题」这一处。 */
.nav > #themeBtn { margin-left: 0; }

/* 语言切换：放在「关于」右边、主题按钮左边（由 i18n.js 插进来）。
   桌面用站内 .dropdown 组件（和排序下拉同一套外观），不用原生 <select> ——
   原生展开后是系统渲染的蓝底白字，跟全站风格差太远。
   选择器要带 #siteNav 提权：.dropdown-toggle 的规则写在后面，同权重会被它盖掉。 */
#siteNav .lang-wrap { margin-left: 0; }
#siteNav .lang-toggle {
  padding: 5px 8px;
  font-size: 12.5px;
  gap: 6px;
  color: var(--text-muted);
  /* ★ 宽度必须跟着**菜单**走，不能跟着当前语言名走。
     菜单里最长的一行是「简体中文」（≈78px），所以按钮固定 82px：
       中文 82 / English 74.7 / 日本語·한국어 69.5 —— 只要按钮比菜单窄，
     菜单就一定会往某一边探出去（压到「关于」或「深色」）。
     为了不让「English」看起来空一截，内容改成**居中**（不再用 space-between
     把箭头顶到最右边），空白就只剩左右各 3px，基本看不出来。 */
  min-width: 82px;
  justify-content: center;
}
#siteNav .lang-toggle:hover { color: var(--text); }
#siteNav .lang-toggle[aria-expanded="true"] {
  border-color: var(--border-strong);
  background: var(--surface-2);
}
#siteNav .lang-wrap .dropdown-menu {
  /* 居中在按钮下方：菜单比按钮宽的那一两像素左右均分，
     既不会伸到「关于」下面，也不会伸到「深色」下面。
     --menu-shift 由 site.js 的 initDropdown 在靠边时写入（窄窗口夹回视口）。 */
  left: 50%;
  right: auto;
  transform: translateX(calc(-50% + var(--menu-shift, 0px)));
}
#siteNav .lang-wrap .dropdown-item { font-size: 12.5px; padding: 6px 8px; }

/* 手机端不用下拉，改成**一整排**按钮：四个语言一眼看全，少点一次。
   两套 DOM 都由 i18n.js 的 mountSwitcher 建，这里只负责切换显示。 */
.lang-row { display: none; }

/* ============================ 按钮 ============================ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  line-height: 1.4;   /* 必须显式设：<button> 默认 line-height:normal，而 <a> 会继承 body 的 1.65，两者高度会差 5px */
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
  white-space: nowrap;
}
/* ⚠️ hover 效果只在**真的能悬停**的设备上生效。
   触屏上点一下之后 :hover 会一直挂着不消失，列表行/按钮看起来就像「一直被预点击、
   一直深色」（用户 2026-10-18 反馈）。触屏用 :active 给即时反馈就够了。 */
@media (hover: hover) and (pointer: fine) {
  .btn:hover { background: var(--surface-2); text-decoration: none; }
  .btn-primary:hover { background: var(--accent); filter: brightness(0.94); }
}
.btn:active { filter: brightness(0.96); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }

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

.btn-sm { padding: 6px 12px; font-size: 13px; }

.btn-danger { border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger-soft); border-color: var(--danger); }

.icon-btn {
  display: grid;
  place-items: center;
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 13px;
  font-family: inherit;
  transition: 0.14s;
}

/* ============================ 首屏 ============================ */

.hero {
  padding: 68px 0 46px;
  text-align: center;
}

.hero h1 {
  margin: 0 0 14px;
  font-size: clamp(28px, 4.6vw, 42px);
  line-height: 1.2;
  font-weight: 700;
  letter-spacing: -0.5px;
}

.hero p.lead {
  margin: 0 auto 28px;
  max-width: 560px;
  color: var(--text-muted);
  font-size: clamp(14.5px, 1.8vw, 16.5px);
}

.hero-search {
  display: flex;
  gap: 8px;
  max-width: 540px;
  margin: 0 auto;
}

.hero-search input {
  flex: 1;
  padding: 11px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 15px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.14s, box-shadow 0.14s;
}
.hero-search input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.hero-search input::placeholder { color: var(--text-dim); }

/* ============================ 区块 ============================ */

.section { padding: 38px 0; }

.section-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 18px;
  flex-wrap: wrap;
}

.section-head h2 {
  margin: 0;
  font-size: 19px;
  font-weight: 600;
}

.section-head .sub {
  margin: 2px 0 0;
  color: var(--text-muted);
  font-size: 13.5px;
}

/* ============================ 页头 ============================ */
.page-head { padding: 38px 0 4px; }

.page-head h1 {
  margin: 0 0 6px;
  font-size: clamp(23px, 3.2vw, 30px);
  font-weight: 700;
  letter-spacing: -0.3px;
}

.page-head p {
  margin: 0;
  color: var(--text-muted);
  font-size: 14.5px;
}

.breadcrumb {
  font-size: 14.5px;
  color: var(--text-dim);
  margin-bottom: 10px;
}
.breadcrumb a { color: var(--text-muted); font-weight: 500; }

/* 面包屑下面那对「上一页 / 下一页」箭头（点击委托在 site.js）。
   用户要求「返回调大」：整个站上唯一用来「返回」的就是上面那条面包屑，
   所以面包屑字号也一并调大，而这对按钮比它再大一点、给足点击区域。
   放在每个带面包屑的页面上（含三个 JS 渲染的详情页）—— 只放管理页的话，
   点「上一页」退到没按钮的页面后，「下一页」就再也找不回来了。 */
.hist-nav { display: flex; gap: 8px; margin: 0 0 12px; }
.hist-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 15px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 1.4;      /* <button> 默认 normal，与 <a> 不一行 */
  cursor: pointer;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
}
.hist-btn:active { background: var(--accent-soft); }

/* 歌词区上方那排按钮（目前只有「复制歌词」）。 */
.ly-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin: 16px 0 8px;
}

/* ============================ 提示条 ============================ */

.notice {
  display: flex;
  gap: 10px;
  padding: 13px 16px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 13.5px;
  margin: 16px 0;
  line-height: 1.7;
}
.notice b { color: var(--text); }

/* ============================ 关于页 ============================ */
/* 之前整页全靠内联样式（每个 h2 都挂着 margin-top:34px），间距不一致、
   列表用 <br>+「·」手搓，窄屏一换行就散。这里统一成一套规则。 */

.about h2 {
  margin: 34px 0 10px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.2px;
}
.about h2:first-child { margin-top: 0; }

.about p {
  margin: 0 0 10px;
  color: var(--text-muted);
  font-size: 14.5px;
  line-height: 1.75;
}
.about p:last-child { margin-bottom: 0; }

.about-list {
  margin: 0 0 10px;
  padding-left: 20px;
  color: var(--text-muted);
  font-size: 14.5px;
  line-height: 1.75;
}
.about-list li { margin-bottom: 6px; }
.about-list li:last-child { margin-bottom: 0; }
.about-list b { color: var(--text); }

/* 站点地址：做成两块可点的卡片，放最前面 */
.about-addr {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 10px;
}
.addr-card {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.14s, background 0.14s;
}
.addr-card b { font-size: 14.5px; font-weight: 600; }
.addr-card span { font-size: 12.5px; color: var(--text-muted); }

.about-foot {
  margin-top: 34px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 12.5px;
  line-height: 1.7;
}

/* ============================ 工具栏 ============================ */

.toolbar {
  position: sticky;
  top: var(--header-h);
  z-index: 20;
  padding: 12px 0;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}

.toolbar-row {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  align-items: center;
}

.search-box {
  position: relative;
  flex: 1 1 300px;
  min-width: 200px;
}

.search-box input {
  width: 100%;
  padding: 10px 36px 10px 13px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 14.5px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.14s, box-shadow 0.14s;
}
.search-box input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-box input::placeholder { color: var(--text-dim); }

.search-box .s-clear {
  position: absolute;
  right: 7px;
  top: 50%;
  transform: translateY(-50%);
  border: 0;
  background: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  padding: 4px 6px;
  border-radius: 4px;
  display: none;
}
.search-box .s-clear:hover { color: var(--text); background: var(--surface-2); }
.search-box.has-value .s-clear { display: block; }

select.control {
  padding: 10px 34px 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  cursor: pointer;
  outline: none;

  /* appearance:none 才能让圆角完全由我们控制（各系统/浏览器一致）。
     代价是原生的小箭头也没了，所以下面用 SVG 自己画一个。 */
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath fill='none' stroke='%23667085' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
}
select.control:focus { border-color: var(--accent); }

/* 注意：下拉「展开后的选项列表」是操作系统原生渲染的，网页 CSS 改不了它的圆角。
   所以排序那一处改用自定义下拉（见 site.js 的 initDropdown）。 */

/* ============================ 自定义下拉 ============================ */

.dropdown { position: relative; }

.dropdown-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  /* 原来写死 min-width: 116px —— 「最新上传」实际只需要 ~100px，
     多出来的 16px 就显示为右边一段空白，桌面端看着比手机端宽一截。
     改成按内容自适应，两边一致。 */
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  line-height: 1.4;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.14s, box-shadow 0.14s;
}
.dropdown-toggle:focus-visible,
.dropdown-toggle[aria-expanded="true"] {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
  outline: none;
}

.dropdown-arrow {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-right: 1.6px solid var(--text-muted);
  border-bottom: 1.6px solid var(--text-muted);
  transform: translateY(-2px) rotate(45deg);
  transition: transform 0.16s;
}
.dropdown-toggle[aria-expanded="true"] .dropdown-arrow {
  transform: translateY(1px) rotate(-135deg);
}

/* 展开后的列表：圆角 + 跟站点同一套配色 —— 这正是原生 select 做不到的地方 */
.dropdown-menu {
  position: absolute;
  top: calc(100% + 5px);
  right: 0;
  z-index: 40;
  min-width: 100%;
  margin: 0;
  padding: 5px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 10px 24px rgba(16, 24, 40, 0.1);
  /* 8 个选项约 306px —— 给到 460px 就能整段展开、不需要滚动。
     原来是写死的 300px，加「最近下载」之后刚好差几像素，右下角那条
     系统滚动条就冒出来了。只有窗口很矮（< ~660px）时才真的会滚。 */
  max-height: min(70vh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;   /* 滚到底别带着整页一起动 */
  /* 系统自带的滚动条带上下箭头、灰底，跟站内风格格格不入 → 换成细的 */
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}
/* 旧版 Chromium（< 121）不认上面两个标准属性，用这套伪元素兜底 */
.dropdown-menu::-webkit-scrollbar { width: 8px; }
.dropdown-menu::-webkit-scrollbar-track { background: transparent; }
.dropdown-menu::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
  border: 2px solid transparent;   /* 缩成一条细线，不要顶着左右边 */
  background-clip: content-box;
}
.dropdown-menu::-webkit-scrollbar-thumb:hover {
  background: var(--text-dim);
  background-clip: content-box;
}

.dropdown-item {
  padding: 8px 10px;
  border-radius: 5px;
  font-size: 13.5px;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.dropdown-item[aria-selected="true"] {
  color: var(--accent);
  background: var(--accent-soft);
  font-weight: 500;
}

.result-info {
  color: var(--text-muted);
  font-size: 13.5px;
  margin-bottom: 12px;
}
.result-info b { color: var(--text); }

/* ============================ 文件列表 ============================ */

.file-list {
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.file-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.14s;
}

/* 整行可点（→ 字幕详情页，点击委托在 subs.js）：
   给个可点的光标 + 接近游戏页卡片的 hover 反馈，
   否则鼠标扫过没有任何提示，看不出这行能点。
   ⚠️ hover 只在真能悬浮的设备上生效 —— 触屏点一下之后 :hover 会一直挂着，
   行背景永远停在 surface-2，看起来像「被预点击了一直是深色」（用户 2026-10-18 反馈）。 */
.file-row[data-href] { cursor: pointer; }
@media (hover: hover) and (pointer: fine) {
  .file-row:hover { border-color: var(--border-strong); }
  .file-row[data-href]:hover { background: var(--surface-2); }
}
.file-row[data-href]:active { border-color: var(--border-strong); }

/* 缩略图（有图时替掉格式徐章）。固定成 160×90（16:9）。
   没有缩略图的行用同样尺寸的 .placeholder 占位，这样列表左边缘永远对齐。 */
.file-thumb {
  flex: 0 0 auto;
  width: 160px;
  height: 90px;
  border-radius: 6px;
  border: 1px solid var(--border);
  object-fit: cover;
  background: var(--surface-2);
}

.file-thumb.placeholder {
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-muted);
}
.file-thumb.placeholder.ass,
.file-thumb.placeholder.ssa { color: var(--accent); }
.file-thumb.placeholder.srt,
.file-thumb.placeholder.vtt { color: var(--ok); }

.file-badge {
  flex: 0 0 auto;
  width: 42px;
  height: 32px;
  border-radius: 5px;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
}
.file-badge.ass, .file-badge.ssa { color: var(--accent); }
.file-badge.srt, .file-badge.vtt { color: var(--ok); }

.file-main { flex: 1; min-width: 0; }

.file-name {
  font-weight: 500;
  font-size: 14.5px;
  word-break: break-word;
  line-height: 1.45;
}
/* 名字是进详情页的链接。必须显式压住全局的 a { color: var(--accent) }，
   不然整个字幕库全是蓝字。 */
a.file-name { display: inline-block; color: inherit; text-decoration: none; }
a.file-name:hover { color: var(--accent); text-decoration: underline; }
.file-name mark {
  background: var(--warn-soft);
  color: var(--warn);
  border-radius: 3px;
  padding: 0 2px;
}

.file-sub {
  display: flex;
  gap: 9px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 3px;
  color: var(--text-dim);
  font-size: 12.5px;
}

/* 管理员写的说明（在文件名下方） */
.file-desc {
  margin-top: 3px;
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.6;
  word-break: break-word;
}

.file-actions { display: flex; gap: 10px; flex: 0 0 auto; }

/* 「更多」按钮复制成功时会变成「已复制」（3 字），给个最小宽度免得按钮跳一下宽度。
   52px = 「更多 / 下载」两个字的自然宽度，和旁边的下载按钮一样大；
   原来写 66px（按 3 个字算），结果「更多」看着比「下载」大一圈（用户 2026-10-18 反馈）。 */
.more [data-act="more"] { min-width: 52px; }

/* 「更多」菜单 */
.more { position: relative; }

.more-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 30;
  min-width: 156px;
  /* 屏幕比菜单还窄时（320px 的老手机），至少不能比屏幕宽 */
  max-width: calc(100vw - 16px);
  padding: 5px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 10px 24px rgba(16, 24, 40, 0.1);
}
/* 下边放不下时由 bindMoreMenu 挂上 drop-up，改成往上弹 */
.more-menu.drop-up { top: auto; bottom: calc(100% + 6px); }

.more-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 0;
  border-radius: 5px;
  background: none;
  color: var(--text);
  font-family: inherit;
  font-size: 13.5px;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

/* 复制成功后的短暂提示（比单纯变文字更显眼） */
.more-item.copied { color: var(--ok); }

/* 「下载」二选一菜单：一条字幕同时有 ASS 和 SRT 时才出现。
   比普通「更多」菜单宽，而且每项要写清楚两个版本的区别，
   所以允许换行（.more-item 默认是 nowrap）。 */
.more-dl .more-menu { min-width: 238px; }
.more-dl .dl-item {
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  white-space: normal;
}
.dl-kind { font-family: var(--font-mono); font-size: 13.5px; font-weight: 600; }
.dl-hint { font-size: 12px; color: var(--text-muted); line-height: 1.5; }

/* 菜单项里的提示看不到（菜单已收起），会挂到「更多」按钮上，这里给它同样的绿色 */
.btn.copied {
  color: var(--ok);
  border-color: var(--ok);
  background: var(--ok-soft);
}

/* 按钮里叠了两份文案（见 site.js 的 capHTML）：
   .cap-live 是真正显示的那份，.cap-size 是「已复制」的隐形占位，
   把按钮宽度一次算到够放「已复制」——点复制时按钮不会突然变宽、把整行挤一下。
   叠在同一个 grid 格子里，宽度自动取两者的大值，所以四种语言都不用写死宽度。 */
.cap { display: inline-grid; }
.cap > * {
  grid-area: 1 / 1;
  white-space: nowrap;
  justify-self: center;
}
.cap-size { visibility: hidden; }

.more-num {
  color: var(--text-dim);
  font-family: var(--font-mono);
  font-size: 11.5px;
}

.tag {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 12px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
  white-space: nowrap;
}

.count-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 12px;
  background: var(--ok-soft);
  border: 1px solid var(--border);
  color: var(--ok);
  white-space: nowrap;
}

/* ============================ 空态 / 加载 ============================ */

.empty {
  padding: 56px 20px;
  text-align: center;
  color: var(--text-muted);
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius);
}
.empty .big { font-size: 15px; font-weight: 600; color: var(--text-dim); margin-bottom: 8px; }
.empty h3 { margin: 0 0 6px; color: var(--text); font-size: 16px; font-weight: 600; }
.empty p { margin: 0 auto; font-size: 14px; max-width: 520px; }

.spinner {
  width: 22px;
  height: 22px;
  margin: 36px auto;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* ============================ 分页 ============================ */

.pager {
  display: flex;
  gap: 5px;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
  margin: 26px 0 8px;
}
.pager button {
  min-width: 34px;
  height: 34px;
  padding: 0 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-family: inherit;
  font-size: 13.5px;
  cursor: pointer;
  transition: 0.14s;
}
.pager button.active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.pager button:disabled { opacity: 0.35; cursor: not-allowed; }
.pager .gap { color: var(--text-dim); padding: 0 3px; }

/* ============================ 页脚 ============================ */

.site-footer {
  margin-top: 50px;
  padding: 26px 0 38px;
  border-top: 1px solid var(--border);
  color: var(--text-dim);
  font-size: 13.5px;
}
.site-footer .container {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.site-footer a { color: var(--text-muted); }
.site-footer a:hover { color: var(--accent); }

/* ==========================================================================
   上传助手 /admin/
   ========================================================================== */

.admin-wrap { max-width: 880px; margin: 0 auto; padding: 0 20px; }

.admin-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 20px;
  margin-bottom: 16px;
}

.admin-card > h2 {
  margin: 0 0 6px;
  font-size: 16.5px;
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: 8px;
}
.admin-card > h2 .num,
details.admin-card > summary .num {
  width: 21px;
  height: 21px;
  border-radius: 5px;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
  flex: 0 0 auto;
}
.admin-card > p.hint {
  margin: 0 0 16px;
  color: var(--text-muted);
  font-size: 13.5px;
  line-height: 1.7;
}

/* 卡片内的工具行：搜索框 + 按钮 + 计数 */
.card-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-bottom: 14px;
}
.card-tools .input { flex: 1 1 200px; width: auto; }
.card-tools .result-info { margin: 0; }

.field { margin-bottom: 13px; }
.field label {
  display: block;
  margin-bottom: 5px;
  font-size: 13.5px;
  color: var(--text-muted);
}
.field .tip { font-size: 12.5px; color: var(--text-dim); margin-top: 5px; line-height: 1.65; }

.input, .textarea, select.input {
  width: 100%;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
  font-family: inherit;
  outline: none;
  transition: border-color 0.14s, box-shadow 0.14s;
}
.input:focus, .textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* 多行输入（如游戏的「详细介绍」）。
   只允许竖向拉：允许横向拉的话，用户一拖就把整页撑出横向滚动条。 */
.textarea { resize: vertical; min-height: 104px; line-height: 1.7; }

.field-row { display: flex; gap: 12px; flex-wrap: wrap; }
.field-row > .field { flex: 1 1 220px; margin-bottom: 13px; }

/* 拖拽区 */
.drop {
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  padding: 36px 20px;
  text-align: center;
  cursor: pointer;
  transition: 0.16s;
  background: var(--bg-soft);
}
.drop:hover, .drop.over {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.drop b { display: block; margin-bottom: 4px; font-size: 15px; font-weight: 600; }
.drop span { color: var(--text-dim); font-size: 13px; font-family: var(--font-mono); }

/* 待上传文件行 */
.up-list { display: flex; flex-direction: column; gap: 7px; margin-top: 14px; }

.up-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 13px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  flex-wrap: wrap;
}

.up-icon {
  flex: 0 0 auto;
  min-width: 40px;
  padding: 3px 6px;
  border-radius: 5px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-muted);
}

.up-row .up-main { flex: 1 1 220px; min-width: 0; }
.up-row .up-name { font-size: 13.8px; font-weight: 500; word-break: break-all; line-height: 1.4; }
.up-row .up-sub {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 3px;
  font-size: 12.5px;
  color: var(--text-dim);
}
.up-row .up-act { display: flex; gap: 6px; flex: 0 0 auto; }

/* 字幕管理列表 */
.mg-list { display: flex; flex-direction: column; gap: 10px; }

.mg-row {
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
}

.mg-row .mg-head { display: flex; align-items: center; gap: 11px; }
.mg-row .mg-toggle { flex: 0 0 auto; margin-left: auto; }
/* ⚠️ .mg-row / .mg-head 是游戏管理页也用的类名，下面这一整段只在字幕管理
   （#mgList）里生效 —— 不然游戏列表的整行会白得一个手型光标，
   而它其实点不动（那边没有展开/收起这回事）。 */
#mgList .mg-head { cursor: pointer; }

/* 每行默认**收起**（用户反馈「现在显示的太多，不好找」）——
   一行摊开是六个输入框 + 一排按钮，接近 600px 高，93 条根本翻不动。
   点「编辑」（或点整行头部）才展开，再点一次「收起」。
   ⚠️ 收起只是 display:none：输入框仍在 DOM 里，所以
   captureDrafts() 收集未保存内容、以及草稿回填都不受影响。 */
#mgList .mg-row:not(.open) .mg-edit,
#mgList .mg-row:not(.open) .mg-tools,
#mgList .mg-row:not(.open) .mg-crop { display: none; }

/* 管理行左侧的缩略图预览（与公开列表同尺寸） */
.mg-row .mg-thumb {
  flex: 0 0 auto;
  width: 160px;
  height: 90px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--surface-2);
  display: grid;
  place-items: center;
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-muted);
}
.mg-row .mg-thumb img { width: 100%; height: 100%; object-fit: cover; }

/* 缩略图操作行 */
.mg-tools {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  align-items: center;
  margin-top: 9px;
}
.mg-note { font-size: 12.5px; color: var(--text-dim); }
.mg-note.err { color: var(--danger); }

/* 待确认的裁剪预览 */
.mg-crop {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.mg-crop-img {
  width: 320px;
  height: 180px;
  object-fit: cover;
  border-radius: 5px;
  border: 1px solid var(--border);
  flex: 0 0 auto;
}
.mg-crop-side { flex: 1 1 230px; min-width: 0; }
.mg-crop-note {
  font-size: 12.5px;
  color: var(--text-muted);
  line-height: 1.7;
  margin-bottom: 9px;
}

/* ===== 批量导入缩略图 ===== */
.batch {
  margin-bottom: 14px;
  padding: 13px 15px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg-soft);
}
.batch-head { margin-bottom: 11px; }
.batch-head b { font-size: 14.5px; }
.batch-head .h2-tail {
  display: block;
  margin: 4px 0 0;
  font-size: 12.5px;
  color: var(--text-dim);
  line-height: 1.7;
}
.batch-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 20px 16px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  cursor: pointer;
  text-align: center;
  transition: 0.16s;
}
.batch-drop:hover, .batch-drop.over {
  border-color: var(--accent);
  background: var(--accent-soft);
}
.batch-drop b { font-size: 14px; font-weight: 600; }
.batch-drop span { font-size: 12.5px; color: var(--text-dim); }

.batch-list { display: flex; flex-direction: column; gap: 8px; margin-top: 11px; }
.batch-list:empty { margin-top: 0; }

.batch-row {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  flex-wrap: wrap;
}
.batch-thumb {
  flex: 0 0 auto;
  width: 96px;
  height: 54px;
  object-fit: cover;
  border-radius: 5px;
  border: 1px solid var(--border);
  background: var(--surface-2);
}
.batch-main { flex: 1 1 260px; min-width: 0; }
.batch-file {
  font-size: 13px;
  font-weight: 500;
  word-break: break-all;
  line-height: 1.45;
}
.batch-sub {
  margin: 2px 0 6px;
  font-size: 12px;
  color: var(--text-dim);
  line-height: 1.6;
  font-family: var(--font-mono);
}
.batch-sub b { color: var(--danger); font-weight: 600; }
.batch-sel {
  width: 100%;
  padding: 6px 9px;
  font-size: 13px;
  background: var(--bg);
}
.batch-state {
  flex: 0 0 auto;
  min-width: 72px;
  text-align: right;
  font-size: 12.5px;
  color: var(--text-dim);
}
.batch-state.ok { color: var(--ok); }
.batch-state.err { color: var(--danger); }

@media (max-width: 720px) {
  .batch-thumb { width: 76px; height: 43px; }
  .batch-state { min-width: 0; text-align: left; }
}

.mg-row .mg-edit {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 11px;
}
.mg-row .mg-edit .input { width: 100%; background: var(--surface); }
.mg-row .mg-btns { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 2px; }

/* 原版歌词：单独一块、能往下展开的文本框。
   用户明确要求「添加原歌词时应该往下打开，而不是一行输出完，和描述分开」——
   所以它是一块带虚线框的独立区域，夹在「说明」和「链接」之间。 */
.mg-row .mg-lyrics {
  margin-top: 3px;
  padding: 10px 12px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.mg-lyrics-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 7px;
  font-size: 12.5px;
  color: var(--text-muted);
}
.mg-lyrics-head .h2-tail { margin-left: 0; font-size: 12px; }
.mg-row .mg-lyrics .textarea {
  width: 100%;
  min-height: 96px;
  font-size: 13.5px;
  line-height: 1.75;
}

/* 这条字幕现有的文件版本（ASS / SRT） */
.mg-variants { display: inline-flex; align-items: center; gap: 5px; }
.mg-variants b {
  padding: 2px 7px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface);
  font-family: var(--font-mono);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--text-muted);
}
.mg-variants .v-ass { border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.mg-variants .v-srt { border-color: var(--ok); background: var(--ok-soft); color: var(--ok); }
.mg-variants .v-none { color: var(--text-dim); }

/* ============================ 原版歌词页 ============================ */
/* /subs/lyrics/?id=xxx —— 从列表「更多 → 原版歌词预览」点进来看到的那一页 */

.ly-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin: 10px 0 2px;
  font-size: 13px;
  color: var(--text-dim);
}

.ly-sec {
  margin-top: 16px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.ly-sec > h2 { margin: 0 0 10px; font-size: 16px; font-weight: 600; }

/* 歌词是站主粘进来的纯文本，靠 pre-wrap 保留换行（不用 <br> 拼） */
.ly-text {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 14.5px;
  line-height: 1.95;
  color: var(--text);
}

.ly-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.state {
  display: inline-flex;
  align-items: center;
  padding: 1px 8px;
  border-radius: 4px;
  font-size: 11.5px;
  font-weight: 500;
  border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text-dim);
}
.state.ok { background: var(--ok-soft); color: var(--ok); }
.state.err { background: var(--danger-soft); color: var(--danger); }
.state.busy { background: var(--accent-soft); color: var(--accent); }
.state.skip, .state.wait { background: var(--surface-2); color: var(--text-dim); }

.bar {
  height: 3px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
  margin-top: 6px;
}
.bar > i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 0.2s;
}

/* 连接状态 */
.conn {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  font-size: 13.5px;
  flex-wrap: wrap;
}
.conn .dot-state {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-dim);
  flex: 0 0 auto;
}
.conn.on .dot-state { background: var(--ok); }
.conn.off .dot-state { background: var(--danger); }
.conn .conn-msg { flex: 1 1 190px; color: var(--text-muted); }
.conn .conn-msg b { color: var(--text); }

/* 发送状态提示（两个管理页共用）。
   每次和 GitHub 通信都会亮一下 —— 国内访问 api.github.com 经常慢或超时，
   得能一眼看出「请求到底发出去没有、GitHub 有没有回应」。
   固定在底部中间，pointer-events:none 所以不挡操作。 */
.send-toast {
  position: fixed;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  z-index: 60;
  max-width: min(92vw, 460px);
  padding: 9px 16px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--text);
  font-size: 13.5px;
  line-height: 1.5;
  text-align: center;
  box-shadow: 0 10px 26px rgba(16, 24, 40, 0.18);
  pointer-events: none;
}
.send-toast.sending { border-color: var(--accent); color: var(--accent); }
.send-toast.ok { border-color: var(--ok); color: var(--ok); }
.send-toast.bad { border-color: var(--danger); color: var(--danger); }

/* 保存/发送类按钮的忙碌态：禁用后文字换成「发送中…」，避免连点发两次 */
.btn[aria-busy="true"] { opacity: 0.7; cursor: default; }

/* 日志 / 代码块 */
.log {
  margin-top: 14px;
  max-height: 250px;
  overflow: auto;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 12.3px;
  line-height: 1.8;
  color: var(--text-muted);
  white-space: pre-wrap;
  word-break: break-all;
}
.log .l-ok { color: var(--ok); }
.log .l-err { color: var(--danger); }
.log .l-info { color: var(--accent); }
.log .l-warn { color: var(--warn); }

/* ============================ 下载统计表 ============================ */

/* ---------- 数据概览：趋势图 + Top3（2026-10-17 重做） ---------- */

.chart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  margin: 4px 0 10px;
}

.range-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
}
.range-btn {
  padding: 5px 12px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
  transition: background 0.14s, color 0.14s;
}
.range-btn:hover { color: var(--text); }
.range-btn.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.08);
}

.chart-box {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  padding: 10px 8px 4px;
  margin-bottom: 22px;
}
.chart { display: block; width: 100%; height: auto; }
.ch-grid { stroke: var(--border); stroke-width: 1; stroke-dasharray: 3 4; }
.ch-axis { fill: var(--text-dim); font-size: 10.5px; font-family: var(--font); }
.ch-line { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
/* 站点规范禁止渐变，面积用同色低透明度 */
.ch-area { fill: var(--accent); opacity: 0.08; stroke: none; }
.ch-dot { fill: transparent; cursor: default; }
.ch-dot:hover { fill: var(--accent); opacity: 0.55; }

.top-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 10px;
}
.top-head h3 { margin: 0; font-size: 15.5px; font-weight: 600; }

.top-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(232px, 1fr));
  gap: 10px;
  margin-bottom: 22px;
}
.top-card {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.14s, background 0.14s;
}
.top-rank {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 20px;
  text-align: center;
}
.top-thumb {
  flex: none;
  width: 56px;
  height: 32px;
  border-radius: 4px;
  object-fit: cover;
  background: var(--bg-soft);
}
.top-thumb.no-thumb { display: block; }
.top-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.top-name {
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.top-meta { font-size: 12px; color: var(--text-muted); }

/* 排行的名次列 + 「看下载排行」滚过去时闪一下 */
.stat-table .rank-cell {
  width: 44px;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  text-align: right;
}
.stat-table .ts-cell {
  white-space: nowrap;
  color: var(--text-muted);
  font-size: 12.5px;
}
.table-wrap.flash { animation: tbl-flash 1.2s ease-out; }
@keyframes tbl-flash {
  0% { background: var(--accent-soft); }
  100% { background: transparent; }
}

.table-wrap { overflow-x: auto; }

.stat-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}
.stat-table th,
.stat-table td {
  padding: 9px 11px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
.stat-table th {
  color: var(--text-dim);
  font-weight: 500;
  font-size: 12.5px;
  white-space: nowrap;
}
.stat-table td.num {
  text-align: right;
  font-family: var(--font-mono);
  font-weight: 600;
  white-space: nowrap;
}
.stat-table tbody tr:hover td { background: var(--bg-soft); }
.stat-table .path-cell {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--text-dim);
  word-break: break-all;
}
.stat-table .bar-cell { width: 80px; }
.stat-table .mini-bar {
  height: 4px;
  border-radius: 999px;
  background: var(--accent);
  min-width: 3px;
}

/* ============================ 概览小卡片 ============================ */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
}

.stat {
  background: var(--bg-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 14px;
  text-align: center;
}
.stat b {
  display: block;
  font-size: 22px;
  font-weight: 700;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.stat span {
  display: block;
  margin-top: 2px;
  color: var(--text-muted);
  font-size: 12.5px;
}

/* ============================ 折叠块 ============================ */

details.admin-card > summary {
  cursor: pointer;
  font-size: 16.5px;
  font-weight: 600;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 8px;
}
details.admin-card > summary::-webkit-details-marker { display: none; }
details.admin-card > summary::after {
  content: '展开';
  margin-left: auto;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-dim);
}
details.admin-card[open] > summary::after { content: '收起'; }
details.admin-card[open] > summary { margin-bottom: 14px; }

/* ============================ 游戏页 ============================ */

.game-list { display: flex; flex-direction: column; gap: 12px; }

/* 整张卡片 = 一个进详情页的链接。

   2026-09-21 的两次修改（都是用户反馈）：
   1. 以前头部点一下是「展开截图」，云盘一多下面会排出一行「复制提取码 xxx」按钮，很难看。
      截图和详细介绍移到了详情页。
   2. 后来连下面那排「选择云盘下载 + 查看详情」也去掉了（「移除下面两个，必须打开详情」）——
      现在整张卡只有 .game-head，点哪里都进详情页。

   注意：.game-head 现在是唯一可见块，**四角都要圆**。 */
.game-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition: border-color 0.14s;
}
.game-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 14px;
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
}
.game-head:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 3px var(--accent-soft);
}

.game-cover {
  flex: 0 0 auto;
  width: 160px;
  height: 90px;
  border-radius: 6px;
  border: 1px solid var(--border);
  object-fit: cover;
  background: var(--surface-2);
}
.game-cover.placeholder {
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text-muted);
}

.game-main { flex: 1 1 auto; min-width: 0; }
.game-name { font-size: 15.5px; font-weight: 600; color: var(--text); }
.game-brief { font-size: 13.5px; color: var(--text-muted); margin-top: 3px; }
.game-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 6px;
  font-size: 13px;
  color: var(--text-dim);
}

/* 头部右边的「详情」标签。点击由外层那个 <a> 负责，它只是个视觉提示。
   做成主色（用户要求「详情换个颜色」）——
   卡片上已经没有别的按钮了，它是唯一告诉人「这里可以点」的东西。 */
.game-go {
  flex: 0 0 auto;
  padding: 4px 12px;
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  font-size: 13px;
  font-weight: 500;
  color: var(--accent);
}

/* 截图网格：点一下开灯箱 */
.shots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}
.shots a {
  display: block;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-2);
}
.shots img { display: block; width: 100%; height: auto; }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: grid;
  place-items: center;
  padding: 22px;
  background: rgba(0, 0, 0, 0.82);
  cursor: zoom-out;
}
.lightbox img { max-width: 100%; max-height: 100%; border-radius: 4px; }

/* 字幕详情页的缩略图可以点开放大（逻辑在 sub-detail.js，用的是同一个 .lightbox） */
img.sd-thumb { cursor: zoom-in; }
/* ============================ 游戏详情页 ============================ */
/* /games/detail.html?id=xxx —— 列表卡片点进来看到的那一页。
   列表只留简介，这里放完整信息：大封面 + 下载 + 详细介绍 + 截图。 */

/* 详情页大封面。
   ★ 用 `width: auto` 而不是 `width: 100%`：
   封面图是上传时压缩过的小图（实测这一张只有 308×173），按 `width:100%` 会被拉到
   781px 宽 —— 放大 2.5 倍，看着就是糊的（用户反馈）。
   改成原尺寸显示（窄屏时靠 max-width 自动缩），**绝不放大**。
   想要大的封面就得传一张尺寸更大的图，这方面改 CSS 没用。 */
.gd-cover {
  width: auto;
  max-width: 100%;
  height: auto;
  max-height: 60vh;
  margin-inline: auto;      /* 比容器窄时居中，不要贴左边 */
  object-fit: contain;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
/* 没传封面时的占位块：没有原始尺寸可依，固定成 16:9 的一块 */
.gd-cover.placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: 280px;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.3px;
  color: var(--text-muted);
}

.gd-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-dim);
}

/* 每一块内容用同一张卡片包起来，和列表页的 .game-card 一个视觉体系 */
.gd-sec {
  margin-top: 18px;
  padding: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.gd-sec > h2 {
  margin: 0 0 6px;
  font-size: 16px;
  font-weight: 600;
}
.gd-hint {
  margin: 0 0 14px;
  font-size: 13px;
  color: var(--text-muted);
  line-height: 1.7;
}
.gd-sec > .gd-hint:last-child { margin-bottom: 0; }

/* 详细介绍：站主写的是纯文本，一段一个 <p>（见 game-detail.js） */
.gd-text { font-size: 14.5px; line-height: 1.85; color: var(--text); }
.gd-text p { margin: 0 0 12px; }
.gd-text p:last-child { margin-bottom: 0; }

/* 云盘按钮：每个占一格。点一下直接跳转 + 自动复制提取码（如果有）。
   名字后面标出这个盘自己的提取码 / 「无需提取码」——
   各盘的码不一定一样，不写出来访客不知道该用哪个。 */
.gd-drives {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 10px;
}
.gd-drive {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
  font-weight: 500;
  transition: background 0.14s, border-color 0.14s, color 0.14s;
}
.gd-drive::after { content: '›'; color: var(--text-dim); flex: 0 0 auto; }
.gd-drive-name {
  flex: 1 1 auto;          /* 占满中间，把码和箭头顶到右边 */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.gd-drive-code {
  flex: 0 0 auto;
  font-size: 12.5px;
  font-weight: 400;
  color: var(--text-muted);
}
/* 「无需提取码」比真的码更弱一级，避免抢注意力 */
.gd-drive-code.none { color: var(--text-dim); }

@media (max-width: 720px) {
  .gd-sec { padding: 15px; }
  .gd-drives { grid-template-columns: 1fr; }
}

/* ============================ 字幕详情页 ============================ */
/* /subs/detail/?id=xxx —— 从字幕库整行点进来看到的那一页 */

/* 缩略图：上传时统一压到 640×360，所以放满 640 以内是清晰的，不要再放大 */
.sd-thumb {
  width: 100%;
  max-width: 640px;
  aspect-ratio: 16 / 9;
  height: auto;
  margin-inline: auto;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
}
.sd-thumb.placeholder {
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.3px;
  color: var(--text-muted);
}

.sd-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 12px;
  font-size: 13px;
  color: var(--text-dim);
}

.sd-sec {
  margin-top: 18px;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.sd-sec > h2 { margin: 0 0 6px; font-size: 16px; font-weight: 600; }
.sd-hint { margin: 0 0 14px; font-size: 13px; color: var(--text-muted); line-height: 1.7; }
.sd-sec > .sd-hint:last-child { margin-bottom: 0; }

.sd-dl { display: flex; flex-wrap: wrap; gap: 10px; }

/* 歌词引子：只展示前几行，完整版在歌词页 */
.sd-lyric {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 14px;
  line-height: 1.9;
  color: var(--text-muted);
  margin-bottom: 14px;
}

.sd-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

/* ---------- 游戏管理页（表单 + 预览） ---------- */

.h2-tail { font-size: 13px; font-weight: 400; color: var(--text-dim); margin-left: 8px; }
.req { color: var(--danger); font-size: 12px; font-weight: 500; }
.code-plain {
  font-family: var(--font-mono);
  background: var(--code-bg);
  padding: 1px 6px;
  border-radius: 4px;
}

.preview {
  margin-top: 4px;
  padding: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg-soft);
}
.pv-title { font-size: 12.5px; color: var(--text-dim); margin-bottom: 9px; }
.pv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  gap: 10px;
}
.pv-item {
  position: relative;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface);
}
.pv-item img { display: block; width: 100%; height: 84px; object-fit: cover; }
.pv-tag { display: block; padding: 5px 7px; font-size: 11.5px; color: var(--text-dim); }
.pv-del {
  position: absolute;
  top: 5px;
  right: 5px;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}
.pv-del:hover { background: var(--danger); }

/* 管理列表里的游戏行 */
.mg-row .mg-body { flex: 1 1 auto; min-width: 0; }
.mg-row .mg-name { font-size: 14.5px; font-weight: 600; }
.mg-row .mg-ph {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-muted);
}
.mg-act { display: flex; gap: 6px; flex: 0 0 auto; margin-left: auto; }

/* 管理页：多云盘链接行（可以无限加，每行 = 云盘名 + 链接 + 删除） */
.link-list { display: flex; flex-direction: column; gap: 8px; }
.link-row { display: flex; gap: 8px; align-items: center; }
.link-row .link-url { flex: 1 1 auto; min-width: 0; }
/* 提取码：每个云盘单独填。有的云盘不能设提取码、有的本来就不需要，
   留空即可（输入框里就写着「无需提取码」）。 */
.link-row .link-code { flex: 0 0 150px; }

/* 云盘名：用站内自定义下拉，不用原生 select / datalist。
   原生展开后的候选列表由操作系统渲染，圆角和配色一律改不了。
   复用上面那套 .dropdown 结构，菜单顶部是个输入框（列表里没有的云盘自己写）。 */
.link-row .drive-pick { flex: 0 0 150px; }
.drive-pick .dropdown-toggle { width: 100%; min-width: 0; }
.drive-pick .dropdown-label { overflow: hidden; text-overflow: ellipsis; }
/* 这一格在行首，菜单默认的 right:0 会往屏幕外长 → 改成左对齐 */
.drive-pick .dropdown-menu {
  left: 0;
  right: auto;
  min-width: 214px;
  /* 实际高度由 JS 按上下剩余空间算（见 games-admin.js），这里只是默认值 */
  max-height: 480px;
}
/* 下边放不下时由 JS 挂上 drop-up，改成往上弹 */
.drive-pick .dropdown-menu.drop-up { top: auto; bottom: calc(100% + 5px); }
.drive-sep { height: 1px; margin: 5px 4px; background: var(--border); }
.drive-other { padding: 2px 4px 3px; }
.drive-other .input { padding: 6px 9px; font-size: 13px; }

/* 自定义的文件选择器。
   浏览器原生的 <input type="file"> 会画成「选择文件 | 未选择任何文件」——
   不同系统长得都不一样，跟站内风格也格格不入。
   这里把真正的 input 藏起来，用一个普通按钮去触发它。 */
.filepick { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.filepick-name {
  font-size: 13px;
  color: var(--text-dim);
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.filepick-name.has-file { color: var(--text); }

@media (max-width: 720px) {
  .game-head { flex-wrap: wrap; }
  .game-cover { width: 128px; height: 72px; }
  .game-go { margin-left: auto; }
  .shots { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); }
  .mg-act { margin-left: 0; }
  .link-row { flex-wrap: wrap; }
  .link-row .drive-pick,
  .link-row .link-url,
  .link-row .link-code { flex: 1 1 100%; }
}

/* ============================ 响应式 ============================ */

/* 菜单按钮只在窄屏出现，宽屏必须隐藏。
   必须写在 .icon-btn 之后：两者特异性相同（都是单类选择器），
   写在前面会被 .icon-btn { display: grid } 覆盖，
   结果宽屏也挂着一个点了没任何反应的「菜单」按钮。 */
.nav-toggle { display: none; }

@media (max-width: 720px) {
  /* 移动端展开的菜单：做成一个明确的浮层 ——
     加阴影、加圆角、下面再压一层半透明遮罩（点遮罩就收起）。
     之前只有一块和页面同色的背景，打开后跟页面糊在一起，分不清哪是哪。 */
  .nav {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 10px 14px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: 0 18px 36px rgba(16, 24, 40, 0.16);
    display: none;
  }
  .nav.open { display: flex; }
  .nav a { padding: 10px 12px; }
  .nav-toggle { display: grid; margin-left: auto; }

  /* 小屏导航是纵向菜单：主题按钮改用上边距分隔 */
  .nav > #themeBtn { margin-left: 0; margin-top: 8px; }
  /* 手机端：不显示下拉，改成一整排语言按钮（见 .lang-row） */
  #siteNav .lang-wrap { display: none; }
  #siteNav .lang-row {
    display: flex;
    gap: 6px;
    width: 100%;
    margin-top: 10px;
  }
  #siteNav .lang-chip {
    flex: 1 1 0;
    min-width: 0;
    padding: 9px 2px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text-muted);
    font-family: inherit;
    font-size: 13px;
    line-height: 1.2;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.14s, color 0.14s, border-color 0.14s;
  }
  #siteNav .lang-chip.is-on {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
    font-weight: 600;
  }

  /* 搜索框 + 排序按钮并排一行。
     原来 .search-box 是 flex: 1 1 300px / min-width: 200px，加上下拉的 116px，
     350px 的屏宽根本放不下 → flex-wrap 把排序挤到了第二行。
     手机上让搜索框可自由压缩，排序按内容宽度顶在右边。 */
  .toolbar-row { flex-wrap: nowrap; }
  .toolbar-row .search-box { flex: 1 1 auto; min-width: 0; }
  .toolbar-row .dropdown { flex: 0 0 auto; }

  body.nav-open .nav-toggle {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-soft);
  }

  .hero { padding: 44px 0 30px; }

  /* 窄屏上缩略图收小一点，给文字留位置 */
  .file-thumb,
  .mg-row .mg-thumb { width: 128px; height: 72px; }

  .file-row { flex-wrap: wrap; }
  .file-actions { width: 100%; }
  .file-actions .btn { flex: 1; }

  /* ⚠️ 手机端按钮是**左对齐**排的（.file-actions 占满一整行），
     而 .more-menu 默认是 right:0 —— 即“以按钮右边缘为准往左伸”。
     238px 宽的「下载」菜单从这里会整块伸到屏幕左侧之外，项都点不到。
     所以窄屏改成以按钮**左**边缘为基准，往右展开。
     （万一右边还是放不下，bindMoreMenu 会再算一次并平移回来。） */
  .more-menu { left: 0; right: auto; }
  /* 这里**不能**把 min-width 归零：绝对定位元素没了 min-width 会被
     收窄到按钮的宽度（66px），两项说明文字全挤成一条竖条。 */

  .hero-search { flex-wrap: wrap; }
  .hero-search input { flex: 1 1 100%; }
  .hero-search .btn { flex: 1 1 100%; }

  .site-footer .container { flex-direction: column; }
}

/* 菜单展开时压在下方的遮罩：让「这是个浮层」一目了然，点一下就收起。
   元素由 site.js 在需要时创建，只有窄屏会显示。
   层级：遮罩 45 < .site-header 50 —— 顶栏和「关闭」按钮始终可点。 */
.nav-backdrop { display: none; }
@media (max-width: 720px) {
  body.nav-open .nav-backdrop {
    display: block;
    position: fixed;
    inset: var(--header-h) 0 0 0;
    z-index: 45;
    background: rgba(16, 24, 40, 0.32);
  }
  /* 深色主题下整页本来就是暗的，用同色去压暗几乎看不出来 → 换纯黑加浓 */
  html[data-theme="dark"] body.nav-open .nav-backdrop { background: rgba(0, 0, 0, 0.55); }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

/* ==================== hover 效果统一收口 ====================
   触屏（手机 / 平板 / 触摸屏笔记本）点一下之后，:hover 会一直挂在那个元素上
   不消失 —— 列表行、卡片、菜单项看起来就像「被预点击了一直是深色」
   （用户 2026-10-18 反馈）。
   所以所有 hover 只在真正能悬浮的设备上生效；触屏用 :active 给按下反馈。 */
@media (hover: hover) and (pointer: fine) {
  .nav a:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
  .dropdown-item:hover { background: var(--surface-2); }
  .more-item:hover { background: var(--surface-2); text-decoration: none; }
  .pager button:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
  .dropdown-toggle:hover { border-color: var(--text-dim); }
  .game-card:hover { border-color: var(--border-strong); }
  .game-head:hover { background: var(--surface-2); text-decoration: none; }
  .game-head:hover .game-go { background: var(--accent); color: #fff; }
  .top-card:hover { border-color: var(--accent); background: var(--bg-soft); }
  .addr-card:hover { border-color: var(--accent); background: var(--bg-soft); }
  .icon-btn:hover { color: var(--text); background: var(--surface-2); }
  .hist-btn:hover { background: var(--surface-2); border-color: var(--accent); color: var(--accent); }
  .shots a:hover { border-color: var(--border-strong); }
  .gd-drive:hover {
    background: var(--accent-soft);
    border-color: var(--accent);
    color: var(--accent);
    text-decoration: none;
  }
  .gd-drive:hover::after { color: var(--accent); }
  .gd-drive:hover .gd-drive-code { color: inherit; }
}

/* 触屏的按下反馈（hover 没了也得让人知道点到了） */
@media (hover: none) {
  .nav a:active,
  .dropdown-item:active,
  .more-item:active,
  .game-head:active { background: var(--surface-2); }
  .game-card:active,
  .addr-card:active { border-color: var(--border-strong); }
}

@media print {
  .site-header, .toolbar, .site-footer, .file-actions { display: none !important; }
}
