/* FeedLite · 轻反馈 —— 简洁、克制的基础视觉基调 */
:root{
  --fg:#1f2329; --muted:#6b7280; --line:#e5e7eb; --line-strong:#d7dbe0;
  --bg:#f5f6f8; --card:#ffffff; --brand:#0057B8; --brand-600:#004a9e; --brand-soft:#e8f0f9;
  /* 主题色的两档浅色，供下拉项 hover / 选中使用。
   * 有软件时由 layout.php 按该软件主题色覆写；这里给默认蓝色的一套，
   * 保证后台、首页这类"无当前软件"的页面也有值可用。
   * 为什么不用 CSS color-mix()：实测它配 var(--brand) 在 Chrome 里
   * 会解析成透明（oklab(0 0 0 / 0)），规则匹配上却不生效。 */
  --brand-tint-1:#ecf3fa;   /* hover：与白混 91% */
  --brand-tint-2:#cfe0f1;   /* 选中：与白混 80% */
  --brand-tint-3:#b9d1ea;   /* 选中+hover：与白混 72% */
  /* 顶栏品牌图标：与官网首页同一枚应用图标（内联，离线预览也能显示） */
  --icon-mark:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAADsOAAA7DgHMtqGDAAADj0lEQVR4nO1b205TQRTdGB/UB78B0BdfRNA3NUT/QPHMHIgaP0BeMPqoog8mJqDyCfoBImJnDuCFyEWhIGiUegONimkFodYEaqpj9qEEwZbS0zOXXlaykqZNO2uvM9M9Z8/ZABkhysBy9gLhl4Dwh0B5CAj7CZQLo4iaCJtwNRLWDITVZI4tY+CMAOGvtQfnnSGwnWNuLFmBBnYAZU8NCMAvDoLlVGwseCtwAAgLGyDaZ7IZsJ3D6wdP+CEg7Jd+sdIYBytQm+bKOxVAecQAkfJngsV3rolelBXYms/EgdV/jJRTA0SpJeF1K1c/v1OdRwPYxFL8dtc+7WJ00Q5U4/S/rF2INrKLkNzeiqIkYfcBCHujXYg+hgAoixkgRBNZDHL5gU22IxraxsXdkYiYnlsUid9/hGzgGDhWRzAi6tvGXQ05mQAev1jZ2CtGp6JCN0Ymo64WpQZUNvaKSDQuTEE4GhcVXk0AD9PehCu/FsH3UW/LAbL8Aq55U2HfGJNvQOdoRJiKO8GwfAO+zi0KU/Hl+6J8AxIKUp1XoDbpBqTCp9kFsftsf/aDe2TVuX7xeXYhpRYtBrR0TikLfpmt9z6YY8DQu3mx5XiXsuC3nuh2054xBiBwe9rzYkZ0P5dLHGO9P2JtBpiCkgG0NANEQaTBbSe7xdWOyfxYAi2S0uD2Uz35YcCQpDRoXRvLDwNkpMEnb+c9bbu1GWAKSgbQ0gwQUpdAIsW69JoGNzc4oq71mW+32Epuh6dT7MNzTYNY2fUDeIss3YCOYMTXNIjV3NhCwhcDbg8pKInVpymKekmDj17O+hY8gl5XUBTdZDu+TVk/MayqLA7JgxE8jDAFqKX8tKKDEfhn7aaryqi+8p5PhWgOBiwvBzyMwHo8lqRVHY7iWO3DYXfNazscBQ88cyuUMcCmmyFlekC1Acgr7env8fEz1XpA+YDJ88WP31bq+vga39OhBbQMmtwG72p67BJf69IB2gY2haBbgG4C5T+0i9BFwqNQlI/JrnpclrIHxf6gZLN2Ifp4Hg2oKd4ZwKuSzRI8VHzBs1crDRPYWqZbkGragSNrWmb4oHZRysj6/u8lpKy8aJqmsC8yTc9grdtapl2kNMaBsoMZeged/QXbOIl9kRuC5fYQDhRQ8H3uEs8OArvJ6tztovYAckh1lB2FnGEHqt0GI9w6uoaY2GXCYkvt86iRXwDL2bOR0P4Cy8Hrhv+SooQAAAAASUVORK5CYII=");
  --ok:#0f9d58; --ok-soft:#e9f7ef; --warn:#b7791f; --warn-soft:#fff8e6;
  --danger:#d93025; --danger-soft:#fdecea; --shadow:0 1px 3px rgba(16,24,40,.06);
  /* ── 表单控件尺度（2026-11-04 统一）──
   * 用户：「输入框、下拉框高度太随意，一点设计感都没有。」
   * 之前 padding 有 8px/9px/12px 三种，select 和 input 高度还不一样，
   * 并排放在一起参差不齐。现在只保留三档，全部按高度对齐：
   *   --ctl-h-sm  32px  表格内 / 紧凑行
   *   --ctl-h    38px  常规表单（默认）
   *   --ctl-h-lg 42px  主要操作区
   * 高度用固定值 + line-height 居中的方式，而不是靠 padding 撑，
   * 这样 input / select / button 放同一行时基线必然一致。 */
  --ctl-h-sm:32px; --ctl-h:38px; --ctl-h-lg:42px;
  --ctl-r:9px;              /* 统一圆角 */
  --ctl-px:12px;            /* 统一左右内边距 */
  --ctl-bd:1px solid var(--line-strong);
  --ctl-shadow:0 1px 2px rgba(16,24,40,.04);
  --ctl-shadow-focus:0 0 0 3px var(--brand-soft);
}
*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--bg); color:var(--fg);
  font-family:-apple-system,BlinkMacSystemFont,"HarmonyOS Sans SC","HarmonyOS Sans","PingFang SC","Helvetica Neue","Microsoft YaHei",sans-serif;
  font-size:15.5px; line-height:1.75; letter-spacing:.01em;
}
.wrap{max-width:880px; margin:0 auto; padding:0 16px}
a{color:var(--brand); text-decoration:none}
a:hover{text-decoration:underline}
h1{font-size:23px; margin:0 0 8px; font-weight:700}
h2{font-size:17px; margin:0 0 12px; font-weight:700}
p{margin:8px 0}
.muted{color:var(--muted)}
.small{font-size:13px}
.dot{color:var(--line-strong); padding:0 2px}

/* ---------- 顶栏（与官网首页同一套导航样式） / 页脚 ---------- */
.topbar{
  position:sticky; top:0; z-index:20;
  background:rgba(255,255,255,.82);
  backdrop-filter:saturate(180%) blur(14px);
  -webkit-backdrop-filter:saturate(180%) blur(14px);
  border-bottom:1px solid var(--line);
  /* 软件抽屉是 absolute + top:100%，需要它来做定位参照，否则会跑到页面最上面 */
}
.topbar .wrap{display:flex; align-items:center; gap:14px; min-height:66px; padding-top:9px; padding-bottom:9px; position:relative; box-sizing:border-box}
/* 顶栏品牌位：**左图标 + 右文字列**两栏
 *
 *      [📅]  同步日历反馈系统        ← 文字列
 *            优秀的鸿蒙CalDav同步客户端
 *
 * 🔴 用户 2026-11-03：「图标应该在标题和简介的正中间…
 *    让标题和它下面的简介合起来和图标高度一样，两个对齐上下。」
 *    ⇒ 图标的垂直中线要与**两行文字整体**的中线重合，不是只对齐第一行。
 *
 * ⚠️ 关键在 align-items:center 作用在「图标 vs 文字列」这一层：
 *    图标是 .brand-ic，文字列是 .brand-txt（内部再上下排 title/note）。
 *    以前图标和标题被包在同一个 .sw-badge 里（单行结构），
 *    note 挂在它下面，图标天然只能对齐第一行 —— 那种结构做不到居中。
 */
.topbar .brand-mini{display:flex; flex-direction:row; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0; line-height:1.25}
.topbar .brand-mini:hover{text-decoration:none; color:var(--fg)}
/* 图标：固定 30×30 的方框，自身内容居中，不参与文字行高计算 */
.topbar .brand-ic{
  width:30px; height:30px; flex:none;
  display:flex; align-items:center; justify-content:center;
  border-radius:9px; overflow:hidden;
}
.topbar .brand-ic img{width:30px; height:30px; object-fit:contain; display:block; border-radius:9px}
.topbar .brand-ic-ch{
  font-size:17px; line-height:1; color:var(--swc, var(--brand)); font-weight:700;
}
/* 文字列：上下两行，自己成一组 */
.topbar .brand-txt{display:flex; flex-direction:column; justify-content:center; gap:1px; min-width:0}
.topbar .brand-title{
  font-size:17px; font-weight:700; letter-spacing:.2px; line-height:1.25;
  color:var(--swc, var(--brand));
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.topbar .brand-mini-note{
  font-size:12.5px; font-weight:400; color:var(--muted);
  line-height:1.3;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
  max-width:520px;
}
/* 顶栏里的软件标识：17px 字 + 32px 图标 ——
 * 比「选择软件」标签(13.5px)大两号，又不至于压过内容区标题。 */
.topbar .brand-mini .sw-badge{gap:9px}
.topbar .brand-mini .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px}
@media (max-width:560px){
  .topbar .wrap{min-height:60px; padding-top:8px; padding-bottom:8px}
  .topbar .brand-mini{font-size:15.5px; gap:8px}
  .topbar .brand-ic{width:26px; height:26px}
  .topbar .brand-ic img{width:26px; height:26px}
  .topbar .brand-ic-ch{font-size:15px}
  .topbar .brand-title{font-size:15.5px}
  .topbar .brand-mini-note{font-size:11.5px; max-width:60vw}
  .topbar .brand-mini .sw-badge-nm{font-size:15.5px}
  .topbar .brand-mini .sw-badge-img{width:26px !important; height:26px !important}
  .topbar .brand-mini .sw-badge{gap:7px}
}

/* ---------- 右上角三横线按钮 + 下拉菜单 ---------- */
.sw-toggle{
  flex:none; width:38px; height:38px; padding:0; margin-left:2px;
  display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  background:transparent; border:0; border-radius:9px;
  cursor:pointer;
}
.sw-toggle span{
  display:block; width:18px; height:2px; border-radius:2px;
  background:var(--fg);
}
.sw-toggle:hover{background:var(--brand-soft)}
.sw-toggle[aria-expanded="true"]{background:var(--brand-soft)}

/* ---------- 软件下拉菜单（右上角三横线） ----------
 * 参考家书 FamilyBook 顶栏那个 popup 的做法：**内容多高就多高的小浮窗**，
 * 紧贴按钮下方、宽度由内容撑开，不是铺满整屏的面板，也不加遮罩。
 * 用户 2026-11-03：「不用做那么复杂，就是点了之后拉下来一个很窄的框，
 * 把所有的内容都铺在上面就可以了」。
 *
 * ⚠️ 用过两版都不对：
 *   ① 宽屏横排 / 窄屏竖排两套 —— 手机上和正文撞在一起
 *   ② 整幅 absolute 面板 + 遮罩 —— 太重了，像侧边栏而不是下拉菜单
 * 现在只有这一种形态：小浮窗，贴按钮右侧对齐。 */
.sw-panel{
  position:absolute; top:calc(100% - 4px); right:12px;
  z-index:60;
  min-width:172px; max-width:min(280px, calc(100vw - 24px));
  padding:6px;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:12px;
  box-shadow:0 10px 28px -8px rgba(20,30,50,.28), 0 2px 6px rgba(20,30,50,.08);
  max-height:calc(100vh - 90px);
  overflow:auto;
}
/* 菜单里不再需要「选择软件」这个标题 —— 按钮本身已经说明用途 */
.sw-panel-hd{display:none}
.sw-panel .wrap{padding:0; max-width:none}
/* 一条一行，竖排 */
.sw-panel-list{display:flex; flex-direction:column; gap:1px}
.sw-item{
  display:flex; align-items:center; gap:8px;
  padding:8px 10px; border-radius:8px; color:var(--fg);
  font-size:14px; white-space:nowrap;
  border:0;
}
.sw-item:hover{background:var(--brand-soft); text-decoration:none; color:var(--fg)}
.sw-item.on{background:var(--brand-soft)}
.sw-item.on .sw-badge-nm{font-weight:700}
.sw-item .sw-badge{gap:7px}
.sw-item .sw-badge-nm{font-size:14px; font-weight:500}
.sw-item .sw-badge-img{width:18px !important; height:18px !important}
/* 「当前」标记缩成一个小圆点，别在窄框里占地方 */
.sw-item-cur{
  margin-left:auto;
  width:6px; height:6px; flex:none; border-radius:50%;
  background:var(--brand);
  font-size:0; line-height:0; overflow:hidden; text-indent:-999px;
}
.topbar .brand-text{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.topbar .logo-mark{
  width:30px; height:30px; flex:none; display:block; border-radius:8px;
  background-image:var(--icon-mark); background-size:cover; background-position:center;
  box-shadow:var(--shadow);
}
.topbar .spacer{flex:1}
.topbar .navlink{color:var(--muted); font-size:14.5px; padding:8px 10px; border-radius:8px; white-space:nowrap}
.topbar .navlink:hover{color:var(--brand); background:var(--brand-soft); text-decoration:none}
.topbar .btn-mini{
  flex:none; font-size:14.5px; font-weight:600; color:#fff; background:var(--brand);
  padding:9px 18px; border-radius:999px; white-space:nowrap;
  box-shadow:0 4px 14px -4px rgba(0,87,184,.55);
}
.topbar .btn-mini:hover{background:var(--brand-600); color:#fff; text-decoration:none}
.hide-sm{display:inline-block}
@media (max-width:640px){
  .hide-sm{display:none}
  .topbar .wrap{gap:10px}
  .topbar .brand-mini{font-size:15.5px; gap:9px}
  .topbar .logo-mark{width:28px; height:28px}
}
main.wrap{padding-top:24px; padding-bottom:40px; min-height:60vh}
.foot{border-top:1px solid var(--line); background:var(--card); padding:22px 0 34px; margin-top:40px}
.foot p{margin:4px 0; text-align:center; font-size:13px; color:var(--muted)}
.foot a{color:var(--muted); text-decoration:underline}
/* 版权句 + 管理后台入口：同一行居中，窄屏自动换行 */
.foot-line{display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:0 6px}
.foot-line .dot{padding:0}

/* ---------- 按钮 ---------- */
/* 按钮高度与输入框严格一致（--ctl-h）。
 * 🔴 原来靠 padding:8px + line-height:1.4 撑，算出来 38.3px，
 *    而输入框是固定 38px —— 并排时差 0.3px，放大看会有轻微的错位感。
 *    改成固定 height + inline-flex 垂直居中，与控件完全同高。 */
.btn{
  display:inline-flex; align-items:center; justify-content:center;
  height:var(--ctl-h); padding:0 16px;
  border:1px solid var(--line-strong); background:var(--card);
  color:var(--fg); border-radius:var(--ctl-r);
  font-size:14.5px; line-height:1;
  cursor:pointer; font-family:inherit; white-space:nowrap;
  box-shadow:var(--ctl-shadow);
  transition:border-color .12s, background .12s, color .12s;
}
.btn:hover{border-color:var(--brand); color:var(--brand); text-decoration:none}
.btn.primary{background:var(--brand); border-color:var(--brand); color:#fff; font-weight:600}
.btn.primary:hover{background:var(--brand-600); color:#fff}

/* ---------- 页头 ---------- */
.page-head{display:flex; align-items:flex-start; gap:16px; margin:6px 0 18px}
.page-head .btn{margin-left:auto; flex:none; margin-top:4px}

/* ---------- 首页：轻反馈介绍页 ----------
 * 用户 2026-11-03：首页不列问题，只做介绍 + 指路。
 * 因为访客总是从某个软件过来的，他要的是「怎么进自己那个软件的反馈」，
 * 而不是看别人的问题列表。 */
.home{max-width:820px; margin:0 auto; padding:8px 0 40px}
.home-hero{text-align:center; padding:26px 0 30px}
.home-hero h1{
  font-size:30px; line-height:1.3; margin:0 0 12px;
  letter-spacing:-.4px;
}
.home-lead{
  font-size:15.5px; line-height:1.75; color:var(--muted);
  margin:0 auto; max-width:600px;
}

.home-feats{
  display:grid; grid-template-columns:repeat(2, minmax(0,1fr));
  gap:12px; margin:0 0 34px;
}
@media (max-width:600px){ .home-feats{grid-template-columns:1fr} }
.home-feat{
  background:var(--card); border:1px solid var(--line);
  border-radius:12px; padding:16px 18px;
}
.home-feat-ic{font-size:20px; line-height:1; margin-bottom:8px}
.home-feat h3{margin:0 0 6px; font-size:15px; font-weight:700}
.home-feat p{margin:0; font-size:13.5px; line-height:1.7; color:var(--muted)}

.home-enter{
  background:var(--card); border:1px solid var(--line);
  border-radius:14px; padding:22px 24px;
}
.home-enter h2{margin:0 0 10px; font-size:17px}
.home-enter-tip{
  font-size:14px; color:var(--muted); line-height:1.8; margin:0 0 16px;
  display:flex; align-items:center; flex-wrap:wrap; gap:6px;
}
.home-enter-tip b{color:var(--fg); font-weight:600}
/* 小号三横线示意，让「右上角那个设置按钮」有具体形象可对照 */
.home-menu-demo{
  display:inline-flex; flex-direction:column; justify-content:center; gap:2.5px;
  width:22px; height:22px; padding:4px; box-sizing:border-box;
  border:1px solid var(--line-strong); border-radius:6px;
  background:var(--bg, #f6f8fb);
}
.home-menu-demo i{display:block; width:100%; height:1.5px; background:var(--fg); border-radius:2px}

.home-sw-list{display:flex; flex-direction:column; gap:8px}
.home-sw{
  display:flex; align-items:center; gap:12px;
  padding:11px 14px; border-radius:11px;
  border:1px solid var(--line); background:var(--card);
  color:var(--fg);
}
.home-sw:hover{
  text-decoration:none; color:var(--fg);
  border-color:var(--swc); background:var(--bg, #f6f8fb);
}
.home-sw-ic{
  width:36px; height:36px; flex:none; border-radius:9px;
  display:flex; align-items:center; justify-content:center;
  font-size:22px; line-height:1;
}
.home-sw-ic img{width:36px; height:36px; object-fit:contain; display:block}
.home-sw-nm{font-size:15px; font-weight:600; color:var(--swc)}
.home-sw-go{margin-left:auto; font-size:13px; color:var(--muted); flex:none}
.home-sw:hover .home-sw-go{color:var(--swc)}
.home-enter-alt{margin:12px 0 0}
.page-head h1{margin-bottom:4px}
.page-head .muted{font-size:14px; margin:0}

/* ---------- 后台处理按钮栏 ---------- */
.act-bar{
  margin:0 0 18px; padding:14px 16px;
  background:var(--card); border:1px solid var(--line); border-radius:12px;
}
.act-bar-title{
  font-size:12.5px; font-weight:700; letter-spacing:.5px;
  color:var(--muted); text-transform:uppercase; margin-bottom:10px;
}
.act-bar-body{display:flex; flex-wrap:wrap; gap:8px; align-items:center}
.act-inline{display:inline}
.act-btn{white-space:nowrap}
.act-btn.is-cur{
  opacity:.55; cursor:default;
  box-shadow:none;
}
.act-btn.ok{border-color:#b7dfc2; color:#1e7b3c}
.act-btn.ok:hover:not(:disabled){background:#f0f9f2}
.act-btn.warn{border-color:#f0dfae; color:#8a6a15}
.act-btn.warn:hover:not(:disabled){background:#fff9ec}
.act-state.on{
  display:inline-block; padding:6px 12px; border-radius:99px;
  font-size:12.5px; font-weight:600;
  background:#f0f9f2; color:#1e7b3c; border:1px solid #b7dfc2;
}
.act-hint{
  margin-left:auto; font-size:12.5px; color:var(--muted);
}
@media (max-width:560px){
  .act-hint{margin-left:0; flex-basis:100%}
}
.act-note{
  margin-top:14px; padding-top:14px; border-top:1px dashed var(--line);
}

/* ---------- 软件标识：图标 + 名字（多软件区分的主视觉） ----------
 * 🔴 一律不要背景色：图标本身就是一张图/一个 emoji，再垫一个色块会糊在一起，
 *    反而看不清。直接「图标 + 文字」并排是识别度最高的做法。
 *    邮件模板里有等价的 table 写法，两边观感要对得上。 */
.sw-badge{display:inline-flex; align-items:center; gap:7px; min-width:0; vertical-align:middle}
.sw-badge-ic{
  display:inline-flex; align-items:center; justify-content:center;
  flex:none; line-height:1; letter-spacing:0;
  background:none; border:0; box-shadow:none;
}
.sw-badge-nm{
  font-weight:600; font-size:14px; color:var(--fg);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.sw-badge-sm .sw-badge-nm{font-size:14px}
.sw-badge-md .sw-badge-nm{font-size:16px; font-weight:600}
/* 内容区：只是软件标识，字号刻意小于顶栏标题（17px），
 * 避免「上面的字比下面的小」这种主次颠倒。颜色同样跟随软件主题色。 */
.sw-badge-lg .sw-badge-nm{font-size:15px; font-weight:600; color:var(--swc, var(--fg))}
/* 顶栏主标题：比「选择软件」标签(13.5px)大两号 = 17px，且大于内容区的 15px。
 * 颜色跟随软件主题色（--swc 由 PHP 内联写到 .brand-mini 上），
 * 让「同步日历」「密码生成器」这些标题一眼可辨。 */
.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px; color:var(--swc, var(--fg))}
/* 页头副行：图标 + 软件名 */
/* （已删）.page-sw-id —— 内容区那行软件标识已移除，
 * 软件名与简介统一由顶栏承担，避免与顶栏标题重复。 */
/* 提交页顶部的软件上下文条：同样无背景色，只留一行轻分隔 */
.sw-context{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  margin:0 0 16px; padding:0 0 12px; border-bottom:1px solid var(--line);
}
.sw-context .sw-badge-nm{color:var(--fg)}
/* 后台软件编辑：图标快选 */
.icon-presets{display:flex; gap:4px; flex-wrap:wrap; margin-top:8px}
.icon-preset{
  width:34px; height:34px; border:1px solid var(--line-strong); border-radius:9px;
  background:var(--card); cursor:pointer; font-size:17px; line-height:1; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
}
.icon-preset:hover{border-color:var(--brand); background:var(--brand-soft)}

/* ---------- 软件图标（上传图片） ---------- */
/* 图标图片：外框与字符版完全一致，换图不会让布局跳动 */
/* 图标图片：不留背景、不加圆角底衬，直接贴图 */
.sw-badge-img{
  display:inline-block; object-fit:contain; flex:none;
  background:none; border:0; box-shadow:none;
}
.chip.on .sw-badge-img{box-shadow:0 0 0 1px rgba(255,255,255,.5)}
/* 后台图标上传行 */
.icon-up{display:flex; align-items:flex-start; gap:14px; flex-wrap:wrap; margin-top:6px}
.icon-prev{
  width:56px; height:56px; flex:none; border-radius:12px; overflow:hidden;
  border:1px solid var(--line); background:var(--card);
  display:flex; align-items:center; justify-content:center;
}
.icon-prev img{width:100%; height:100%; object-fit:cover; display:block}
.icon-prev-ph{
  width:100%; height:100%; display:flex; align-items:center; justify-content:center;
  color:#fff; font-size:24px; font-weight:600;
}
.icon-up-main{flex:1; min-width:220px; display:flex; flex-direction:column; align-items:flex-start}
/* ⚠️ 不要在这里给 input[type=file] 设任何样式 ——
 *    它已被 .file-btn 视觉隐藏（clip），设 max-width/font-size 之类
 *    会把它从"视觉隐藏"变成"露出一个小方块"，反而破坏新按钮外观。 */
/* 上传状态提示：选中文件后立刻告诉用户「选到了什么、合不合格」。
 * 用户 2026-11-04：「上传的图标没有显示，也没有成功/失败提示。」 */
.icon-up-tip{
  display:block; margin-top:7px; font-size:12.5px; line-height:1.6;
  color:var(--muted); word-break:break-all;
}
.icon-up-tip.is-ok{color:var(--ok, #16794a)}
.icon-up-tip.is-err{color:var(--danger, #c0392b); font-weight:600}
/* chip 里也不用白底反色了 —— 图标本来就没有底色 */
.chip.on .sw-badge-nm{color:#fff}
.chip .sw-badge-ic{background:none !important; color:inherit !important; box-shadow:none}

/* ---------- 主题色选择器 ---------- */
.sw-dot{
  display:inline-block; width:10px; height:10px; border-radius:50%;
  flex:none; margin-right:2px; vertical-align:middle;
  box-shadow:0 0 0 1px rgba(0,0,0,.12);
}
.color-row{display:flex; align-items:center; gap:10px; flex-wrap:wrap; position:relative}
.color-input{
  width:46px; height:34px; padding:2px; border:1px solid var(--line-strong);
  border-radius:9px; background:var(--card); cursor:pointer; flex:none;
}

/* ---------- 自绘色板 ----------
 * 用户 2026-11-04：「需要一个完整的色板，右侧那些默认颜色就不要了。」
 *
 * 🔴 色板必须 position:fixed —— 后台这个表单在 <details class="tax-form-box">
 *    里面，而它有 overflow:hidden。用 absolute 会被裁掉下半部分，
 *    连带色相条一起看不见，用户就以为"只有蓝色"（只能看到当前色相）。
 *    fixed 直接相对视口定位，任何祖先的 overflow 都管不到它。
 *    位置由 JS 按触发按钮的坐标算出来写进 style。 */
.color-trigger{
  display:inline-flex; align-items:center; gap:9px;
  padding:5px 12px 5px 6px; height:34px;
  border:1px solid var(--line-strong); border-radius:9px;
  background:var(--card); cursor:pointer; flex:none;
  font-size:13px; font-family:ui-monospace,Menlo,Consolas,monospace;
  color:var(--fg);
}
.color-trigger:hover{border-color:var(--brand)}
.color-trigger-chip{
  width:22px; height:22px; border-radius:6px; flex:none;
  background:var(--cur, #0057B8);
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.10);
}
.color-trigger-hex{font-weight:600; letter-spacing:.2px}
.color-trigger-caret{font-size:10px; color:var(--muted); margin-left:1px}

.cp{
  position:fixed; z-index:9999;
  width:372px; padding:14px;
  background:var(--card); border:1px solid var(--line-strong);
  border-radius:14px; box-shadow:0 12px 36px rgba(16,24,40,.24);
  user-select:none; box-sizing:border-box;
}
.cp-hd{
  font-size:12.5px; font-weight:700; color:var(--muted);
  letter-spacing:.3px; margin:0 0 10px;
}
/* 画布容器：相对定位，光标挂在这里面，坐标计算就不用管面板 padding */
.cp-sv-wrap{position:relative; border-radius:9px; overflow:hidden; line-height:0}
.cp-sv{
  display:block; width:100%; height:200px; border-radius:9px;
  cursor:crosshair;
}
.cp-cursor{
  position:absolute; width:15px; height:15px; margin:-7.5px 0 0 -7.5px;
  border:2px solid #fff; border-radius:50%; pointer-events:none;
  box-shadow:0 0 0 1px rgba(0,0,0,.4), 0 1px 3px rgba(0,0,0,.3);
}
/* 两条滑条：色相 + 明度
 * 🔴 色相条必须**看得出是光谱** —— 用户反馈「好像只有蓝色」，
 *    是因为之前色相条被 overflow 裁掉了，只看到上面那片蓝色的 HSV 板。
 *    所以这里把色相条做高（18px）、加圆角描边，一眼就知道"能选所有颜色"。 */
.cp-slider{margin:12px 0 0}
.cp-slider input[type=range]{
  -webkit-appearance:none; appearance:none; width:100%; height:18px; border-radius:9px;
  outline:none; cursor:pointer; display:block;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.10);
}
.cp-hue input[type=range]{
  background:linear-gradient(to right,
    #f00 0%, #ff0 17%, #0f0 33%, #0ff 50%, #00f 67%, #f0f 83%, #f00 100%);
}
.cp-val input[type=range]{background:linear-gradient(to right, #000, #fff)}
.cp-slider input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none; width:20px; height:20px; border-radius:50%;
  background:#fff; border:2px solid #fff;
  box-shadow:0 0 0 1px rgba(0,0,0,.45), 0 1px 4px rgba(0,0,0,.3); cursor:pointer;
}
.cp-slider input[type=range]::-moz-range-thumb{
  width:18px; height:18px; border-radius:50%; background:#fff;
  border:2px solid #fff; box-shadow:0 0 0 1px rgba(0,0,0,.45); cursor:pointer;
}
.cp-foot{display:flex; align-items:center; gap:8px; margin-top:13px}
.cp-preview{
  width:30px; height:30px; border-radius:8px; flex:none;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.12);
}
.cp-hex{
  flex:1; min-width:0; height:30px; padding:0 9px;
  border:1px solid var(--line-strong); border-radius:8px;
  font-family:ui-monospace,Menlo,Consolas,monospace; font-size:13px;
  text-transform:uppercase; background:var(--card); color:var(--fg);
}
.cp-ok{flex:none; height:32px !important; padding:0 14px !important; font-size:13px !important}
.color-presets{display:flex; gap:6px; flex-wrap:wrap}
.color-preset{
  width:26px; height:26px; border-radius:50%; border:2px solid transparent;
  cursor:pointer; padding:0; flex:none; transition:transform .12s;
}
.color-preset:hover{transform:scale(1.12)}
.color-preset.on{border-color:var(--fg); box-shadow:0 0 0 2px var(--card) inset}

/* ---------- 邮件测试 ---------- */
.mail-test{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px;
  padding:12px 14px; margin:6px 0 16px;
  background:var(--card); border:1px dashed var(--line); border-radius:11px;
}
.mail-test input[type=email]{
  flex:1 1 220px; min-width:180px;
  /* 边框/高度/圆角统一在「统一表单控件」段里定义，这里只管宽度 */
}
.mail-test-out{flex:1 1 100%; font-size:13px; line-height:1.6}
.mail-test-out.ok{color:var(--ok)}
.mail-test-out.err{color:#c9302c}

/* RAM 角色探测结果 */
.role-ok{
  padding:8px 11px; border-radius:9px; font-size:13.5px;
  background:var(--ok-soft, #eef8f0); border:1px solid #cfe8d5;
}
.role-warn{
  padding:8px 11px; border-radius:9px; font-size:13.5px;
  background:#fff8e6; border:1px solid #f0e0b0; color:#8a6d1f;
}

/* ---------- 表单就地校验的错误提示 ---------- */
.field.has-error > input,
.field.has-error > textarea,
.field.has-error > select,
.field.has-error .chips{
  border-color:#d9534f !important;
  box-shadow:0 0 0 3px rgba(217,83,79,.12) !important;
}
.field-error{
  display:block; margin-top:6px; font-style:normal;
  font-size:12.5px; color:#c9302c; line-height:1.5;
}
.field-error::before{content:"⚠ "; font-style:normal}

/* ---------- 后台：软件 / 分类 / 状态 ---------- */
.card-list{display:flex; flex-direction:column; gap:8px; margin-bottom:16px}
.tax-row{
  display:flex; align-items:flex-start; gap:12px; flex-wrap:wrap;
  padding:12px 14px; background:var(--card); border:1px solid var(--line);
  border-radius:11px;
}
.tax-row.on{border-color:var(--brand); box-shadow:0 0 0 1px var(--brand) inset}
.tax-row.off{opacity:.62}
.tax-main{flex:1 1 320px; min-width:0}
.tax-name{font-weight:600; font-size:15.5px; text-decoration:none; color:var(--fg)}
.tax-name:hover{color:var(--brand)}
.tax-name.plain{font-weight:600}
.tax-slug{
  display:inline-block; margin-left:8px; font-size:12px; color:var(--muted);
  font-family:ui-monospace,Consolas,monospace;
}
.tax-meta{margin-left:10px; font-size:12.5px; color:var(--muted)}
.tax-note{margin-top:5px; font-size:13px; color:var(--muted); line-height:1.5}
.tax-acts{display:flex; flex-wrap:wrap; gap:6px; align-items:center}
.inline-form{display:inline}
/* 小号按钮：基类是固定 height，这里必须显式改 height 而不是改 padding，
 * 否则 padding 会被 height 吃掉、按钮还是 38px 高。 */
.btn.sm{height:var(--ctl-h-sm); padding:0 11px; font-size:13px; border-radius:8px}
.btn.danger{border-color:#e0b4b4; color:#b4242c}
.btn.danger:hover{background:#fdf2f2; border-color:#b4242c}
.tax-form-box{
  margin:18px 0 8px; border:1px solid var(--line); border-radius:11px;
  background:var(--card); overflow:hidden;
}
.tax-form-box>summary{
  cursor:pointer; padding:12px 14px; font-weight:600; font-size:14.5px;
  background:var(--bg-soft, #f7f8fa); user-select:none;
}
.tax-form-box>summary:hover{color:var(--brand)}
.tax-form-box[open]>summary{border-bottom:1px solid var(--line)}
.sm-form{padding:14px; margin:0}
.sm-form .field{margin-bottom:10px}

/* ---------- 软件切换（一级） ---------- */
.software-bar{
  display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin-bottom:14px; padding-bottom:14px; border-bottom:1px solid var(--line);
}
.software-bar .sw-label{font-size:13.5px; color:var(--muted); font-weight:600}
.software-bar .chips{margin-bottom:0}

/* ---------- 筛选（二级：分类 / 状态） ---------- */
/* ---------- 筛选区 ----------
 * 用户 2026-11-04：「筛选的时候，反馈类型和后面的下拉框不在一条线上；
 *   如果反馈类型比较多，下拉框就被挤到下一行去了。建议统一成分两行，
 *   这样也就没有对齐的问题了。」
 *
 * 之前的问题：.filters 是 flex + flex-wrap，分类 chips 和筛选表单
 * 被当成同一行的兄弟元素，分类一多就把表单挤下去，
 * 而且两者高度不同（chips 是胶囊、表单是控件），永远对不齐。
 *
 * 现在：**固定两行，各管各的**
 *   第 1 行 = 反馈类型 chips（可换行，不影响别的）
 *   第 2 行 = 状态/排序/搜索框/搜索按钮（同一行，高度一致）
 * 两行之间用间距分隔，不再有"谁挤谁"的问题。
 *
 * ⚠️ 这里必须显式写 flex-direction:column 覆盖旧的 display:flex ——
 *    文件后面还有一处 .filters 定义（管理后台用），
 *    如果只在 HTML 里加类容易漏，直接在这里定死纵向布局最稳。 */
.filters{display:flex; flex-direction:column; gap:10px; margin:18px 0 4px}
/* chips 基础布局（原来的行内样式被合并到这里，别漏） */
.chips{display:flex; flex-wrap:wrap; gap:8px}
/* 第 1 行：分类 chips */
.filters .chips{margin-bottom:0}
/* 第 2 行：筛选表单，自己内部横向排列 */
.filters .filter-row{display:flex; flex-wrap:wrap; gap:9px; align-items:center}
/* 后台的筛选栏是纯控件、没有分类 chips，所以要横排 ——
 * 用 .filters-row 覆盖掉前台的两行纵向布局。
 * ⚠️ 必须放在 .filters 之后（同一优先级后者生效）。 */
.filters.filters-row{flex-direction:row; flex-wrap:wrap; gap:9px; align-items:center}
.chip{
  padding:5px 13px; border-radius:999px; background:var(--card);
  border:1px solid var(--line); font-size:13.5px; color:var(--fg);
}
.chip:hover{border-color:var(--brand); color:var(--brand); text-decoration:none}
.chip.on{background:var(--brand); border-color:var(--brand); color:#fff; font-weight:600}
.filter-row{display:flex; flex-wrap:wrap; gap:9px; align-items:center}
/* 控件的具体样式统一在上面的「统一表单控件」段里定义（避免多处覆盖打架） */

/* ---------- 列表 ---------- */
.list{display:flex; flex-direction:column; gap:12px}
.item{
  display:block; background:var(--card); border:1px solid var(--line);
  border-radius:13px; padding:15px 17px; box-shadow:var(--shadow); color:inherit;
}
.item:hover{border-color:var(--brand); text-decoration:none; box-shadow:0 3px 12px rgba(0,87,184,.10)}
/* 列表项：
 * 行1 = 标题（顶头、单独一行）
 * 行2 = 分类 / 状态 标签
 * 行3 = 摘要、缩略图、作者信息
 *
 * 🔴 用户 2026-11-03：标签别放在标题前面。
 *    以前 badges 和标题挤在同一个 flex 行里，标签占掉左边一大截，
 *    标题被推到右边、长度不够就换行，很难看。
 *    现在标题独占一行、从左边缘开始，标签另起一行。 */
/* ⚠️ .item-top 仍被 admin.php 的三处内部列表使用（后台待审核 / 详情头 / 操作日志）。
 *    前台列表已改用 .item-head + .item-tags（标题独占一行），这里保留供后台用。 */
.item-top{display:flex; align-items:center; flex-wrap:wrap; gap:8px}
.item-head{display:flex; align-items:flex-start; gap:8px}
.item-title{font-weight:600; font-size:16px; flex:1; min-width:0; line-height:1.45; word-break:break-word}
.item-tags{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:7px}
.item-ex{color:var(--muted); font-size:14px; margin:8px 0 8px; word-break:break-word}
.item-meta{display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:13px; color:var(--muted)}
.item-meta .who{color:#3a424d; font-weight:600}

/* 带 token 回复时展示只读身份（昵称 + 邮箱） */
.reply-identity{
  display:flex; align-items:center; flex-wrap:wrap; gap:8px;
  padding:9px 12px; border-radius:9px;
  background:var(--bg, #f6f8fb); border:1px solid var(--line);
  font-size:14px;
}
.reply-identity-nm{font-weight:600; color:var(--fg)}
.reply-identity-mail{
  color:var(--muted); font-size:13px;
  padding:1px 8px; border-radius:99px; background:var(--card);
  border:1px solid var(--line);
}

/* 提交人凭 token 看自己未公开反馈时的提示条 */
.owner-note{
  display:flex; flex-direction:column; gap:4px;
  margin:0 0 16px; padding:12px 14px;
  background:var(--warn-soft, #fff8e6);
  border:1px solid #f0d9a8; border-left:3px solid #d99b1f;
  border-radius:10px; font-size:13.5px; line-height:1.65;
  color:#6b5313;
}
.owner-note b{font-size:14px; color:#5a4610}

/* ---------- 后台「待审核」列表 ----------
 * 列表式：一屏能看多条，右侧固定一个「通过并公开」。
 * 详情/关闭说明留在管理页里填，列表页不塞表单。 */
.plist{display:flex; flex-direction:column; gap:10px}
.prow{
  display:flex; align-items:flex-start; gap:16px;
  background:var(--card); border:1px solid var(--line);
  border-radius:12px; padding:13px 16px;
}
.prow:hover{border-color:var(--line-strong)}
.prow-main{flex:1; min-width:0}
/* 后台待审核条目：标题顶头独占一行 → 标签行 → 摘要 → 作者信息
 * ⚠️ .prow-top 仍被「操作日志」那处复用（日志条目只有动作+编号，单行更合适），
 *    所以这里保留它，另外新增 .prow-head / .prow-tags 给反馈条目用。 */
.prow-top{display:flex; align-items:center; flex-wrap:wrap; gap:8px}
.prow-head{display:flex; align-items:flex-start; gap:8px}
.prow-tags{display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:7px}
.prow-title{
  font-weight:600; font-size:15.5px; color:var(--fg);
  flex:1; min-width:0; word-break:break-word; line-height:1.45;
}
.prow-title:hover{color:var(--brand); text-decoration:underline}
.prow-ex{
  color:var(--muted); font-size:13.5px; margin:6px 0;
  word-break:break-word; display:-webkit-box; -webkit-line-clamp:2;
  -webkit-box-orient:vertical; overflow:hidden;
}
.prow-meta{display:flex; flex-wrap:wrap; align-items:center; gap:6px; font-size:12.5px; color:var(--muted)}
.prow-meta .who{color:#3a424d; font-weight:600}
.prow-act{flex:none; padding-top:2px}
.prow-act .btn{white-space:nowrap}
@media (max-width:600px){
  .prow{flex-direction:column; gap:10px}
  .prow-act{align-self:flex-start}
}
/* 问题编号：便于按 id 逐条跟进与引用 */
.item-id{
  flex:none; font-size:12.5px; font-weight:600; color:var(--muted);
  font-variant-numeric:tabular-nums; letter-spacing:.02em;
  border:1px solid var(--line); border-radius:6px; padding:0 7px; line-height:1.9;
}

/* ---------- 徽标 ---------- */
.badge{
  display:inline-block; font-size:12px; line-height:1.6; padding:1px 9px;
  border-radius:999px; background:var(--brand-soft); color:var(--brand);
  font-weight:600; white-space:nowrap;
}
.badge.st{background:#f1f3f5; color:#5b636e}
.badge.st-open{background:var(--warn-soft); color:var(--warn)}
/* 「未公开」= 还没审过，用中性灰，不要和「已关闭」混淆 */
.badge.st-hidden{background:#eef0f3; color:#6b7684}
.badge.st-doing{background:var(--brand-soft); color:var(--brand)}
.badge.st-resolved{background:var(--ok-soft); color:var(--ok)}
.badge.st-closed{background:#f1f3f5; color:#8a929c}
.badge.official{background:var(--brand); color:#fff}
/* 软件徽章：比分类更"重"，一眼看出属于哪个软件 */
/* 软件徽标：每个软件用自己的主题色 + 图标，方便一眼区分是哪个软件。
 * 颜色由 PHP 内联写入（--swc / --swc-soft），这里只管形态。 */
.badge.sw{
  display:inline-flex; align-items:center; gap:5px;
  background:var(--swc-soft, #eef2f8); color:var(--swc, #2b4a74);
  /* ⚠️ 不要加 border —— 用户 2026-11-03 指出「两个标签中间加个线干嘛」。
   *    分类/状态标签都没有边框，只有软件标签有，并排显示时那道描边
   *    看起来就像凭空插了一条分隔线。统一成无边框的胶囊。 */
  font-weight:600;
  padding:1px 9px 1px 6px;
}
.badge.sw .badge-sw-ic{
  display:inline-flex; align-items:center; justify-content:center;
  width:15px; height:15px; flex:none; line-height:1;
}
.badge.sw .badge-sw-ic img{width:15px; height:15px; display:block; object-fit:contain}
.badge.sw .badge-sw-nm{white-space:nowrap}
.badge.st-wontfix{background:#f6eef0; color:#a13c53}

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

/* ---------- 空态 ---------- */
.empty{
  background:var(--card); border:1px dashed var(--line-strong); border-radius:13px;
  padding:34px 20px; text-align:center; color:var(--muted);
}
.empty.small{padding:20px}

/* ---------- 面包屑 ---------- */
.crumbs{margin:4px 0 14px; font-size:14px}

/* ---------- 主题 / 回复 ---------- */
.subject{background:var(--card); border:1px solid var(--line); border-radius:14px; padding:20px 22px; box-shadow:var(--shadow)}
/* 详情页三段：标题（顶头独占一行）→ 标签行 → 作者信息行。
 * 🔴 用户 2026-11-03：软件名/分类/状态这三个标签原来在标题前面，
 *    把标题挤到右边去了。现在标题在最上面顶头，标签另起一行放下面。 */
.subject-head{display:flex; align-items:flex-start; gap:10px}
.subject-title{font-size:21px; margin:0; flex:1; min-width:0; line-height:1.4; word-break:break-word}
.subject-tags{display:flex; flex-wrap:wrap; align-items:center; gap:7px; margin:10px 0 0}
.subject-body{margin-top:14px; white-space:normal; word-break:break-word; line-height:1.85}
.subject-body br{content:""}

.replies{margin-top:22px}
.reply{
  background:var(--card); border:1px solid var(--line); border-left:3px solid var(--line-strong);
  border-radius:11px; padding:13px 16px; margin-bottom:11px;
}
.reply.admin{border-left-color:var(--brand); background:linear-gradient(180deg,var(--brand-soft),var(--card) 42%)}
.reply-head{display:flex; align-items:center; gap:8px; font-size:13px; color:var(--muted); margin-bottom:6px}
.reply-head .who{font-weight:600; color:#3a424d; font-size:14px}
.reply-body{word-break:break-word; line-height:1.8}

/* ---------- 表单 ---------- */
/* ══════════════════════════════════════════════════════════════
 * 统一表单控件（2026-11-04 重做）
 *
 * 用户：「输入框、下拉框、选择图片那个按钮、排序输入框、前端筛选的
 *      输入框下拉框，都特别丑，一点设计感都没有。高度太随意。」
 *
 * 之前的问题：
 *   ① 样式散落在 5-6 处（.field / .filter-row / .filters / .admin 各自一套）
 *   ② padding 有 8px / 9px / 12px 三种，select 与 input 高度不等，
 *      并排放一起参差不齐
 *   ③ select 用浏览器默认箭头，各平台样式不一，还贴边
 *   ④ file input 完全是原始外观
 *
 * 现在：一套基类 .ctl + 统一变量，所有控件高度/圆角/边框/聚焦环一致。
 * 高度用「固定 height + line-height 居中」而不是 padding 撑，
 * 保证 input / select / button 同行时基线必然对齐。
 * ══════════════════════════════════════════════════════════════ */

/* --- 基类：所有文本类控件 ---
 * 🔴 选择器要**宽松**。之前限定在 .field / .filters 里面，
 *    结果任何不在这些容器里的控件（后台零散布局里的 select、input）
 *    都退化成浏览器默认外观，高度只有 19~21px，跟旁边 38px 的按钮并排
 *    参差不齐 —— 这正是用户说的"高度太随意"。
 *    现在按 type 通吃，再用 :not() 排除掉不该套的（checkbox/radio/color/file/range）。 */
input[type=text]:not(.cp-hex),
input[type=email],
input[type=tel],
input[type=password],
input[type=url],
input[type=number],
input[type=search],
select,
textarea:not(.cp-hex){
  height:var(--ctl-h);
  padding:0 var(--ctl-px);
  border:var(--ctl-bd);
  border-radius:var(--ctl-r);
  background:var(--card);
  color:var(--fg);
  font-family:inherit;
  font-size:14.5px;
  line-height:calc(var(--ctl-h) - 2px);   /* 减掉上下边框，垂直居中 */
  box-shadow:var(--ctl-shadow);
  transition:border-color .12s, box-shadow .12s;
  -webkit-appearance:none;
  appearance:none;
}
/* 文本域不能用固定高度 */
textarea{height:auto; min-height:110px; padding:9px var(--ctl-px); line-height:1.7; resize:vertical}
/* 数字框保留原生上下箭头（用户要改排序，有箭头更直观） */
input[type=number]{-moz-appearance:auto; appearance:auto; -webkit-appearance:auto}

/* --- 聚焦态：统一一圈柔和的 brand 光晕 --- */
input[type=text]:focus, input[type=email]:focus, input[type=tel]:focus,
input[type=password]:focus, input[type=url]:focus, input[type=number]:focus,
input[type=search]:focus, select:focus, textarea:focus{
  outline:none;
  border-color:var(--brand);
  box-shadow:var(--ctl-shadow-focus);
}

/* --- 悬停：边框略深，给出可交互暗示 --- */
input[type=text]:hover:not(:focus), input[type=email]:hover:not(:focus),
input[type=tel]:hover:not(:focus), input[type=password]:hover:not(:focus),
input[type=url]:hover:not(:focus), input[type=number]:hover:not(:focus),
input[type=search]:hover:not(:focus), select:hover:not(:focus),
textarea:hover:not(:focus){
  border-color:#c3c9d1;
}

/* --- 下拉框：自绘箭头 ---
 * 原生箭头各平台差异大且贴边。这里用内联 SVG 画一个 12px 的 V 形，
 * 右侧留 34px 空间，再给 padding-right 避开它。
 * ⚠️ 背景必须同时写 background-color 和 background-image，
 *    否则 -webkit-appearance:none 后底色会丢失。 */
.field select,
.filter-row select,
.filters select,
select{
  padding-right:34px;
  background-color:var(--card);
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236b7280' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 12px center;
  cursor:pointer;
}
select:hover{
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%231f2329' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* --- 搜索框：左侧放大镜图标 --- */
.filter-row input[type=search]{flex:1; min-width:170px; padding-left:36px;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='15' height='15' viewBox='0 0 15 15'%3E%3Ccircle cx='6.2' cy='6.2' r='4.6' fill='none' stroke='%236b7280' stroke-width='1.5'/%3E%3Cpath d='M9.8 9.8 13.4 13.4' stroke='%236b7280' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:12px center;
}
/* 去掉 Chrome 自带的搜索框清除按钮（和我们的图标风格不搭） */
.filter-row input[type=search]::-webkit-search-decoration,
.filter-row input[type=search]::-webkit-search-cancel-button{
  -webkit-appearance:none; appearance:none;
}

/* --- 文件选择按钮：把原生丑控件重做成一个真正的按钮 ---
 * 用户：「选择图片那个按钮太丑。」
 * 做法：隐藏原生 input（但不能 display:none，否则不可点/不可聚焦），
 * 用 <label class="file-btn"> 包一个自绘按钮，点击穿透到 input。 */
.file-btn{
  display:inline-flex; align-items:center; gap:9px;
  height:var(--ctl-h); padding:0 14px 0 12px;
  border:var(--ctl-bd); border-radius:var(--ctl-r);
  background:var(--card); color:var(--fg);
  font-size:14px; font-weight:600; cursor:pointer;
  box-shadow:var(--ctl-shadow);
  transition:border-color .12s, background .12s;
  max-width:100%;
}
.file-btn:hover{border-color:var(--brand); background:var(--brand-soft); color:var(--brand)}
.file-btn:active{transform:translateY(.5px)}
.file-btn-ic{
  width:17px; height:17px; flex:none;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 3v10M6 9l4 4 4-4M4 16h12' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3E%3Cpath d='M10 3v10M6 9l4 4 4-4M4 16h12' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
}
.file-btn-name{
  font-weight:400; color:var(--muted); font-size:13px;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:190px;
}
/* 原生 input 视觉隐藏，但仍可点击/可聚焦（不能用 display:none） */
.file-btn input[type=file]{
  position:absolute; width:1px; height:1px; opacity:0;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap;
}

/* --- 数字框 + 前后缀，让「排序」这种小输入看起来有设计感 --- */
.num-wrap{display:inline-flex; align-items:center; gap:0; position:relative}
.num-wrap .num-suffix{
  position:absolute; right:12px; font-size:12.5px; color:var(--muted);
  pointer-events:none;
}
.num-wrap input[type=number]{padding-right:44px}

/* ---------- 自定义下拉（替换原生 select 的展开列表）----------
 * 用户 2026-11-04：「下拉框拉下来之后怎么全是灰色的？不好看，重新设计。」
 *
 * 🔴 原生 <select> 的展开列表由浏览器绘制，CSS 改不动（只能改 option 底色），
 *    各平台样式还不统一。所以必须自绘。
 *    但**不重写 HTML**：原生 select 保留参与提交，JS 在旁边生成按钮+浮层。
 *    这样全站 16 个 select 自动获得新样式，也不会破坏 onchange 内联逻辑。
 */

/* 原生 select：视觉隐藏但仍参与表单提交与事件（不能 display:none） */
.sel-native{
  position:absolute !important;
  width:1px !important; height:1px !important;
  margin:0 !important; padding:0 !important; border:0 !important;
  opacity:0 !important; pointer-events:none !important;
  clip:rect(0 0 0 0) !important;
}

/* 外层：inline-flex 让它跟输入框一样参与行内布局 */
.sel{position:relative; display:inline-flex; vertical-align:middle; max-width:100%}

/* 触发按钮：外观与普通输入框完全一致（同高同圆角同边框） */
.sel-btn{
  display:inline-flex; align-items:center; gap:10px;
  height:var(--ctl-h); padding:0 12px;
  border:var(--ctl-bd); border-radius:var(--ctl-r);
  background:var(--card); color:var(--fg);
  font-family:inherit; font-size:14.5px; line-height:1;
  cursor:pointer; text-align:left;
  box-shadow:var(--ctl-shadow);
  transition:border-color .12s, box-shadow .12s;
  max-width:100%; min-width:0;
}
.sel-btn:hover{border-color:#c3c9d1}
.sel-btn:focus-visible{outline:none; border-color:var(--brand); box-shadow:var(--ctl-shadow-focus)}
/* 「打开态」样式统一在下方 .sel-btn.is-open 处定义（含主题色底） */
.sel-txt{
  flex:1; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
/* 未选择任何值时（如「全部状态」）文字用次要色，弱化存在感 */
.sel-btn.is-placeholder .sel-txt{color:var(--muted)}
/* 自绘箭头：默认灰，**打开或有选中值时用主题色** ——
 * 让下拉在视觉上跟当前软件一致（用户要的就是这个）。 */
.sel-caret{
  width:11px; height:7px; flex:none;
  background:currentColor; opacity:.55;
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1.2 5.5 5.8 10 1.2' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='7' viewBox='0 0 11 7'%3E%3Cpath d='M1 1.2 5.5 5.8 10 1.2' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:transform .16s, background .12s, opacity .12s;
}
/* 打开时箭头转 180° 并变成主题色 —— 明确"这个下拉是激活的"，
 * 同时和主题色呼应。 */
.sel-btn.is-open .sel-caret{
  transform:rotate(180deg);
  background:var(--brand);
  opacity:1;
}
/* 打开时按钮整体也染上主题色：
 * 浅主题底 + 主题边框，不用再靠外圈光晕强调。 */
.sel-btn.is-open{
  border-color:var(--brand);
  background:var(--brand-soft);
  color:var(--brand-600);
  box-shadow:var(--ctl-shadow-focus);
}
.sel-btn.is-open .sel-txt{color:var(--brand-600); font-weight:600}

/* 浮层：fixed 定位，不被任何 overflow 容器裁切。
 * 用白底 + 细边框 + 柔和阴影，而不是浏览器默认的灰块。 */
.sel-panel{
  position:fixed; z-index:9998;
  max-height:min(320px, calc(100vh - 32px));
  overflow-y:auto; overscroll-behavior:contain;
  padding:5px;
  background:var(--card);
  border:1px solid var(--line-strong);
  border-radius:11px;
  box-shadow:0 10px 30px rgba(16,24,40,.16), 0 2px 6px rgba(16,24,40,.06);
  animation:selIn .12s ease-out;
}
@keyframes selIn{ from{opacity:0; transform:translateY(-4px)} to{opacity:1; transform:none} }
.sel-panel.is-up{animation-name:selInUp}
@keyframes selInUp{ from{opacity:0; transform:translateY(4px)} to{opacity:1; transform:none} }

/* 列表项：圆角、行高一致、hover 有底色、选中项有对勾 */
.sel-item{
  display:flex; align-items:center; gap:8px; width:100%;
  padding:0 10px; height:34px;
  border:0; border-radius:7px;
  background:transparent; color:var(--fg);
  font-family:inherit; font-size:14px; line-height:1;
  cursor:pointer; text-align:left; white-space:nowrap;
  transition:background .1s, color .1s;
  -webkit-appearance:none; appearance:none;
}
.sel-item-txt{flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis}

/* hover / 键盘高亮：主题色最浅一档。
 * 用户 2026-11-04：「下拉框就用那个软件的主题颜色，挺好看的。」
 *   （上一版我误判成中性灰，已改回主题色系。）
 * ⚠️ 用 PHP 算好输出的 --brand-tint-1，不用 color-mix()：
 *    实测 color-mix(in srgb, var(--brand) 9%, #fff) 在此环境解析成透明。 */
.sel-item:hover, .sel-item.is-active{
  background:var(--brand-tint-1);
  color:var(--brand-600);
}

/* 选中项：比 hover 深一档 + 主题色文字 + 右侧对勾，
 * 一眼看出当前选的是哪个，也让"我在哪个软件的反馈系统里"更明确。 */
.sel-item.on{
  background:var(--brand-tint-2);
  color:var(--brand-600);
  font-weight:600;
}
.sel-item.on:hover, .sel-item.on.is-active{
  background:var(--brand-tint-3);
  color:var(--brand-600);
}
.sel-item-ck{
  width:13px; height:10px; flex:none;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='10' viewBox='0 0 13 10'%3E%3Cpath d='M1.5 5.2 4.8 8.4 11.5 1.6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='13' height='10' viewBox='0 0 13 10'%3E%3Cpath d='M1.5 5.2 4.8 8.4 11.5 1.6' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
}

/* 窄屏：让下拉至少占满可用宽度，别挤成一小坨 */
@media (max-width:640px){
  .sel{flex:1 1 auto; min-width:0}
  .sel-btn{width:100%}
}

/* ---------- 提交页容器 */
 * 🔴 原来只有 max-width:640px，**没有居中** —— 在 880px 的内容区里，
 *    表单贴左边、右侧空出 240px 白，看起来像"页面缺了一块"。
 *    用户 2026-11-03 指出这一点。现在：加 margin 居中，宽度放到 720px，
 *    既不至于像正文那么宽（长行难读），也不会显得抠掉一块。 */
.narrow{max-width:720px; margin-left:auto; margin-right:auto}

/* ---------- 提交成功页 ----------
 * 用户 2026-11-03：提交完不要跳走，要给回执 + 凭据 + 后续去处。 */
.submitted{
  background:var(--card); border:1px solid var(--line);
  border-radius:16px; padding:30px 32px 26px; margin-top:14px;
  box-shadow:var(--shadow);
  text-align:center;
}
.submitted-ok{
  width:52px; height:52px; margin:0 auto 14px; border-radius:50%;
  background:var(--ok-soft, #e8f6ee); color:var(--ok, #16794a);
  font-size:26px; line-height:52px; font-weight:700;
}
.submitted h1{font-size:22px; margin:0 0 10px}
.submitted-lead{
  font-size:14px; line-height:1.75; color:var(--muted);
  margin:0 auto 20px; max-width:520px;
}
.submitted-lead b{color:var(--fg)}

/* 凭据框：要显眼但不能吓人 —— 用中性浅底 + 等宽字，看起来像"码" */
.token-box{
  text-align:left; margin:0 0 22px; padding:15px 16px;
  background:var(--bg, #f6f8fb); border:1px solid var(--line);
  border-radius:11px;
}
.token-box-hd{
  font-size:12.5px; font-weight:700; color:var(--muted);
  letter-spacing:.3px; margin-bottom:8px;
}
.token-code{
  font-family:ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size:14px; font-weight:600; color:var(--fg);
  padding:10px 12px; background:var(--card);
  border:1px dashed var(--line-strong); border-radius:8px;
  word-break:break-all; user-select:all; line-height:1.5;
}
.token-box-tip{
  font-size:12.5px; line-height:1.7; color:var(--muted); margin:10px 0 0;
}
.token-box-warn{
  font-size:12.5px; line-height:1.7; color:#8a5a10; margin:8px 0 0;
  padding:7px 10px; background:#fff8e6; border-radius:6px;
}

.submitted-next{
  font-size:13px; color:var(--muted); margin:0 0 10px; text-align:left;
}
.submitted-actions{
  display:flex; flex-wrap:wrap; gap:8px; justify-content:flex-start;
  margin:0 0 22px;
}

/* （已删）submitted-others / submitted-sw ——
 * 成功页不再列其他软件的入口，跨软件只有顶栏三横线菜单一个入口。 */

.submitted-credit{
  margin:18px 0 0; padding-top:16px; border-top:1px solid var(--line);
  font-size:12.5px; color:var(--muted); text-align:left;
  word-break:break-all;
}
@media (max-width:600px){
  .submitted{padding:24px 18px 20px}
  .submitted-actions .btn{flex:1 1 auto; text-align:center}
}
.card-form{background:var(--card); border:1px solid var(--line); border-radius:14px; padding:20px 22px; box-shadow:var(--shadow); margin-top:14px}
.field{display:block; margin-bottom:16px}
.field > span{display:block; font-size:14px; font-weight:600; margin-bottom:6px}
.field .req{color:var(--danger)}
.field .hint{font-style:normal; font-weight:400; font-size:12.5px; color:var(--muted); margin-left:6px}
/* 控件的边框/高度/圆角/聚焦态统一在上方「统一表单控件」段里定义。
 * 这里只保留 .field 的宽度约束 —— 表单里的控件一律占满整行。 */
.field > input[type=text],
.field > input[type=email],
.field > input[type=tel],
.field > input[type=password],
.field > input[type=url],
.field > input[type=number],
.field > input[type=search],
.field > select,
.field > textarea{width:100%}
/* 短小的数字类字段（如「排序」）不该铺满整行 —— 收窄到 140px，
 * 视觉上更像"一个小参数"而不是"一个大输入框"。 */
.field-narrow{max-width:140px}
.field-narrow > input{width:100% !important}
@media (max-width:560px){ .field-narrow{max-width:none} }
.row2{display:grid; grid-template-columns:1fr 1fr; gap:14px}
@media (max-width:560px){ .row2{grid-template-columns:1fr} }

.captcha{margin:18px 0 0; padding:14px 16px; background:#fafbfc; border:1px solid var(--line); border-radius:11px}
.captcha .field{margin-bottom:0}
.captcha-line{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.captcha-line .c-q{
  flex:1; min-width:200px; font-weight:600; color:var(--brand);
  background:var(--brand-soft); border-radius:8px; padding:8px 12px;
}
.captcha-line input{flex:none; width:110px}
.captcha-line .reload{font-size:13.5px; white-space:nowrap}

.form-actions{margin-top:20px}
.form-actions .btn{padding:10px 26px; font-size:15px}
.admin-status{margin-bottom:16px}

/* 蜜罐字段：对用户不可见，但保留在 DOM 中诱捕机器人 */
.hp-field{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden}

/* ---------- 提示条 ---------- */
.flash{border-radius:10px; padding:11px 15px; font-size:14px; margin:0 0 16px}
.flash.error{background:var(--danger-soft); border:1px solid #f6c6c1; color:#9c2b21}
.flash.ok{background:var(--ok-soft); border:1px solid #bfe5cd; color:#0b6b3d}

/* ---------- 附件上传（浏览器直传 OSS） ---------- */
.uploader-box{
  margin:18px 0 0; padding:14px 16px; background:#fafbfc;
  border:1px solid var(--line); border-radius:11px;
}
.uploader{border-radius:10px; transition:background .15s, box-shadow .15s}
.uploader + .uploader{margin-top:14px; padding-top:14px; border-top:1px dashed var(--line)}
.uploader.dragging{background:var(--brand-soft); box-shadow:0 0 0 2px var(--brand) inset}
.up-head{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.up-title{font-size:14px; font-weight:600}
.up-head .btn{margin-left:auto; padding:6px 14px; font-size:13.5px; flex:none}
.up-file{display:none}
.up-list{display:flex; flex-wrap:wrap; gap:9px; margin-top:10px}
.up-list:empty{display:none}
.up-item{
  position:relative; display:flex; gap:10px; align-items:center; width:100%;
  padding:8px 10px; border:1px solid var(--line); border-radius:10px; background:var(--card);
}
.up-thumb{
  width:52px; height:52px; flex:none; border-radius:8px; overflow:hidden; background:#eef1f4;
  display:flex; align-items:center; justify-content:center;
}
.up-thumb img{width:100%; height:100%; object-fit:cover; display:block}
.up-thumb-video{font-size:10px; font-weight:700; color:var(--muted); letter-spacing:.08em}
.up-info{flex:1; min-width:0}
.up-name{font-size:13.5px; font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.up-state{font-size:12.5px; color:var(--muted); word-break:break-word}
.up-bar{height:4px; border-radius:2px; background:#e6eaee; overflow:hidden; margin-top:5px}
.up-bar i{display:block; height:100%; width:0; background:var(--brand); transition:width .2s}
.up-item.done .up-bar{display:none}
.up-item.fail{border-color:#f6c6c1; background:var(--danger-soft)}
.up-item.fail .up-state{color:var(--danger)}
.up-del{
  flex:none; border:1px solid var(--line-strong); background:var(--card); color:var(--muted);
  border-radius:7px; padding:5px 10px; font-size:12.5px; cursor:pointer; font-family:inherit;
}
.up-del:hover{border-color:var(--danger); color:var(--danger)}
.up-del:disabled{opacity:.45; cursor:default}

/* ---------- 附件展示 ---------- */
/* align-items:flex-start —— 否则同行里有视频（多了标题栏）时，图片盒子会被拉伸，底部留白 */
.atts{display:flex; flex-wrap:wrap; align-items:flex-start; gap:10px; margin-top:14px}
.atts .att{
  margin:0; max-width:100%; border:1px solid var(--line); border-radius:11px;
  overflow:hidden; background:var(--card);
}
.atts .att-image img{display:block; width:220px; height:auto; max-height:200px; object-fit:cover}
.atts.compact .att-image img{width:150px; max-height:140px}
.atts .att-video{flex:1 1 320px; max-width:440px}
.atts .att-video video{display:block; width:100%; max-height:330px; background:#000}
.att-video-ph{
  width:360px; max-width:100%; height:200px; background:#11161c; color:#8b97a5;
  display:flex; align-items:center; justify-content:center; font-size:13px;
}
.atts figcaption{
  display:flex; gap:8px; align-items:center; padding:6px 9px; font-size:12px; color:var(--muted);
}
.atts .att-name{overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.atts .att-size{margin-left:auto; flex:none}
.thumbs{display:flex; gap:8px; margin:0 0 8px}
.thumbs img{
  width:78px; height:78px; object-fit:cover; display:block;
  border-radius:9px; border:1px solid var(--line);
}
.att-tag{color:var(--brand); font-weight:600}

/* ---------- 附件灯箱（点击放大 + 左右切换） ---------- */
.atts .att-image .att-lb{display:block; line-height:0; cursor:zoom-in}
.atts .att-image .att-lb:focus-visible{outline:2px solid var(--brand); outline-offset:2px}
.att-zoom{
  flex:none; border:1px solid var(--line-strong); background:var(--card); color:var(--muted);
  border-radius:6px; padding:2px 9px; font-size:12px; line-height:1.6; cursor:pointer; font-family:inherit;
}
.att-zoom:hover{border-color:var(--brand); color:var(--brand)}

html.lb-open,body.lb-open{overflow:hidden}
.lb{
  position:fixed; inset:0; z-index:1000; background:rgba(12,14,17,.94);
  display:flex; flex-direction:column; animation:lb-in .16s ease-out;
}
.lb[hidden]{display:none}
@keyframes lb-in{from{opacity:0} to{opacity:1}}
.lb-stage{flex:1; min-height:0; position:relative}
.lb-media{
  position:absolute; inset:0; z-index:1; padding:48px 62px;
  display:flex; align-items:center; justify-content:center;
}
.lb-media img,.lb-media video{
  display:block; max-width:100%; max-height:100%; border-radius:6px;
  box-shadow:0 10px 44px rgba(0,0,0,.55);
}
.lb-media video{background:#000; width:auto}
.lb-media.loading::after{
  content:''; position:absolute; width:26px; height:26px; border-radius:50%;
  border:3px solid rgba(255,255,255,.26); border-top-color:#fff;
  animation:lb-spin .8s linear infinite;
}
@keyframes lb-spin{to{transform:rotate(360deg)}}
.lb-nav{
  position:absolute; top:50%; transform:translateY(-50%); z-index:2;
  width:46px; height:46px; padding:0 0 3px; border:0; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,.14); color:#fff; font-size:26px; line-height:1;
  display:flex; align-items:center; justify-content:center; font-family:inherit;
}
.lb-nav:hover{background:rgba(255,255,255,.32)}
.lb-nav[hidden]{display:none}
.lb-prev{left:14px}
.lb-next{right:14px}
.lb-x{
  position:absolute; top:14px; right:14px; z-index:3;
  width:40px; height:40px; border:0; border-radius:50%; cursor:pointer;
  background:rgba(255,255,255,.14); color:#fff; font-size:17px; font-family:inherit;
}
.lb-x:hover{background:rgba(255,255,255,.32)}
.lb-bar{
  flex:none; display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:10px 18px 16px; color:#e9edf2; font-size:13.5px;
}
.lb-name{font-weight:600; max-width:58vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.lb-meta{color:#9aa4b0; white-space:nowrap}
.lb-orig{margin-left:auto; color:#9ec5ff; white-space:nowrap}
.lb-orig[hidden]{display:none}
@media (max-width:560px){
  .lb-media{padding:40px 10px}
  .lb-nav{width:38px; height:38px; font-size:22px}
  .lb-prev{left:6px} .lb-next{right:6px}
  .lb-name{max-width:44vw}
}

/* ---------- 深色模式 ---------- */
@media (prefers-color-scheme: dark){
  :root{
    --fg:#e6e8eb; --muted:#9aa2ad; --line:#2c3138; --line-strong:#3a4149;
    --bg:#15181c; --card:#1c2024; --brand:#5aa2ff; --brand-soft:#1e2a3d;
    --ok:#4ec98a; --ok-soft:#16301f; --warn:#e2b559; --warn-soft:#2a2517;
    --danger:#ff8a80; --danger-soft:#33191a; --shadow:0 1px 3px rgba(0,0,0,.35);
  }
  .item-meta .who,.reply-head .who{color:#cfd4da}
  .field > span{color:#e6e8eb}
  .captcha{background:#21262b}
  .uploader-box{background:#21262b}
  .up-thumb{background:#2c3138}
  .up-bar{background:#2c3138}
  .up-item.fail{border-color:#5a2a2a}
  .badge.st{background:#242a30; color:#a8b0ba}
  .badge.st-closed{background:#242a30; color:#8a929c}
  .topbar{background:rgba(21,24,28,.82)}
  .topbar .navlink:hover{background:var(--brand-soft)}
  .btn:hover{border-color:var(--brand)}
  .reply.admin{background:linear-gradient(180deg,var(--brand-soft),var(--card) 42%)}
  .flash.error{background:var(--danger-soft); border-color:#5a2a2a; color:#ffb4ab}
  .flash.ok{background:var(--ok-soft); border-color:#26503a; color:#9fe3bd}
}

/* ---- 管理后台 ---- */
.tabs{display:flex; flex-wrap:wrap; gap:8px; margin:16px 0 4px; border-bottom:1px solid var(--line); padding-bottom:10px}
.tab{padding:7px 14px; border-radius:999px; font-size:14px; color:var(--muted); background:var(--card); border:1px solid var(--line)}
.tab:hover{color:var(--brand); border-color:var(--brand)}
.tab.on{background:var(--brand); border-color:var(--brand); color:#fff}
.grid2{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:12px 16px; margin:12px 0}
.grid2 .field{margin:0}
.check{display:flex; align-items:center; gap:8px; font-size:14px; color:var(--muted); margin:8px 0}
.check input{width:16px; height:16px}
.btn.danger{border-color:#e08b84; color:#c0392b}
.btn.danger:hover{background:#fdecea}
/* ⚠️ 这里**不要**再写 .filters{display:flex; flex-wrap:wrap} ——
 *    上面「筛选区」那段已经定死为纵向两行布局，
 *    这里再写横向会把分类和表单挤回同一行（用户明确不要这样）。
 *    只保留对内部控件的宽度约束。 */
.filters .filter-row input[type=text],
.filters .filter-row input[type=search]{flex:1 1 220px; min-width:180px}
.filters .filter-row select{max-width:170px}
@media (max-width:640px){
  .grid2{grid-template-columns:1fr}
  .filters .filter-row input[type=text],
  .filters .filter-row input[type=search],
  .filters .filter-row select{width:100%; max-width:none}
}
