Files
FeedLite/assets/style.css
T
laoyang 2ef119f7cb 标题字号折中;软件选择移入右上角汉堡菜单
用户反馈三点:
1. 顶栏图标太大(56px)
2. 顶栏文字反而比内容区还小 —— 主次颠倒
3. 不要再整页显示「选择软件:」,改成右上角三横线按钮,点开下拉选

字号标准(用户给的基准):
  「选择软件」标签 13.5px,比它大两号 ≈ 17px。
  → 顶栏 17px 字 / 30px 图标;内容区 15px 字 / 24px 图标。
  这样 17 > 15,层级正确。

   之前两轮都搞错了:
   - 先给顶栏 46px 图标 + 22px 字:图标过大
   - 再给 56px + 26px:更大
   - 而且内容区当时是 30px,比顶栏还大,视觉上「上面比下面小」

软件选择改造:
- 顶栏右侧新增汉堡按钮(三横线,展开变×)
- 抽屉面板放在 header 内、正文之上,默认 hidden
- 列出软件:图标 + 名字 + 当前项标记
- index.php 删除整行「选择软件:」+ chips
- new.php 表单内也删除那排 chip(同一选择不该出现两次)
- 交互:点击展开/再点收起/点外部关闭/Esc 关闭
- 宽屏抽屉横向排列,窄屏纵向

验证(CDP 驱动真实浏览器):
汉堡按钮存在、初始收起、点击展开、aria 同步、软件条目与当前标记齐全、
再点收起、点外部关闭 —— 全部 PASS;
顶栏字号 17px > 内容区 15px,页面无裸露 ?>;
全部路由 200;窄屏 15px/13px 层级仍正确。
2026-11-03 08:51:20 +08:00

639 lines
30 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* FeedLite · 轻反馈 —— 简洁、克制的基础视觉基调 */
:root{
--fg:#1f2329; --muted:#6b7280; --line:#e5e7eb; --line-strong:#d7dbe0;
--bg:#f5f6f8; --card:#ffffff; --brand:#0057B8; --brand-600:#004a9e; --brand-soft:#e8f0f9;
/* 顶栏品牌图标:与官网首页同一枚应用图标(内联,离线预览也能显示) */
--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);
}
*{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);
}
.topbar .wrap{display:flex; align-items:center; gap:14px; height:66px}
.topbar .brand-mini{display:flex; align-items:center; gap:10px; font-weight:700; font-size:17px; color:var(--fg); min-width:0}
.topbar .brand-mini:hover{text-decoration:none; color:var(--fg)}
/* 顶栏里的软件标识: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{height:60px}
.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:40px; height:40px; padding:0; margin-left:2px;
display:inline-flex; flex-direction:column; align-items:center; justify-content:center; gap:5px;
background:transparent; border:1px solid var(--line); border-radius:10px;
cursor:pointer;
}
.sw-toggle span{
display:block; width:17px; height:2px; border-radius:2px;
background:var(--fg); transition:transform .18s ease, opacity .18s ease;
}
.sw-toggle:hover{border-color:var(--brand); background:var(--brand-soft)}
.sw-toggle[aria-expanded="true"]{border-color:var(--brand); background:var(--brand-soft)}
/* 展开时变成 × */
.sw-toggle[aria-expanded="true"] span:nth-child(1){transform:translateY(7px) rotate(45deg)}
.sw-toggle[aria-expanded="true"] span:nth-child(2){opacity:0}
.sw-toggle[aria-expanded="true"] span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.sw-panel{
border-top:1px solid var(--line);
background:var(--card);
box-shadow:0 8px 20px -12px rgba(20,30,50,.18);
}
.sw-panel .wrap{padding-top:14px; padding-bottom:16px}
.sw-panel-hd{
font-size:13.5px; font-weight:600; color:var(--muted);
margin-bottom:10px; letter-spacing:.2px;
}
.sw-panel-list{display:flex; flex-direction:column; gap:2px}
.sw-item{
display:flex; align-items:center; gap:10px;
padding:9px 10px; border-radius:10px; color:var(--fg);
}
.sw-item:hover{background:var(--bg, #f6f8fb); text-decoration:none; color:var(--fg)}
.sw-item.on{background:var(--brand-soft)}
.sw-item.on .sw-badge-nm{color:var(--brand); font-weight:700}
.sw-item-cur{
margin-left:auto; font-size:11.5px; font-weight:600; color:var(--brand);
background:var(--card); border:1px solid var(--brand);
padding:1px 8px; border-radius:99px;
}
@media (min-width:561px){
.sw-panel-list{flex-direction:row; flex-wrap:wrap; gap:8px}
.sw-item{padding:7px 12px; border:1px solid var(--line)}
.sw-item.on{border-color:var(--brand)}
.sw-item-cur{margin-left:4px}
}
.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}
/* ---------- 按钮 ---------- */
.btn{
display:inline-block; border:1px solid var(--line-strong); background:var(--card);
color:var(--fg); border-radius:9px; padding:8px 16px; font-size:14.5px;
cursor:pointer; line-height:1.4; font-family:inherit;
}
.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}
.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:19px}
.sw-badge-lg .sw-badge-nm{font-size:22px; font-weight:700}
/* 顶栏主标题:比「选择软件」标签(13.5px)大两号 = 17px。
* 之前给到 26px 反而比内容区标题还小,主次颠倒;这里保持克制。 */
.sw-badge-brand .sw-badge-nm{font-size:17px; font-weight:700; letter-spacing:.2px}
/* 页头副行:图标 + 软件名 */
.page-sw-id{margin:0; display:flex; align-items:center}
/* 提交页顶部的软件上下文条:同样无背景色,只留一行轻分隔 */
.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}
.icon-up-main input[type=file]{font-size:13.5px; max-width:100%}
/* 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}
.color-input{
width:46px; height:34px; padding:2px; border:1px solid var(--line-strong);
border-radius:9px; background:var(--card); cursor:pointer; flex:none;
}
.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;
border:1px solid var(--line-strong); border-radius:9px; padding:8px 10px;
font-size:14px; background:var(--card); color:var(--fg); font-family:inherit;
}
.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}
.btn.sm{padding:5px 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}
/* ---------- 筛选(二级:分类 / 状态) ---------- */
.filters{margin-bottom:16px}
.chips{display:flex; flex-wrap:wrap; gap:8px; margin-bottom:12px}
.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:8px}
.filter-row select,.filter-row input[type=search]{
border:1px solid var(--line-strong); border-radius:9px; padding:8px 10px;
font-size:14px; background:var(--card); color:var(--fg); font-family:inherit;
}
.filter-row input[type=search]{flex:1; min-width:160px}
/* ---------- 列表 ---------- */
.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)}
.item-top{display:flex; align-items:center; flex-wrap:wrap; gap:8px}
.item-title{font-weight:600; font-size:16px; flex:1; min-width:160px}
.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}
/* 问题编号:便于按 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-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}
/* 软件徽章:比分类更"重",一眼看出属于哪个软件 */
.badge.sw{background:#eef2f8; color:#2b4a74; border:1px solid #cfdcee; font-weight:600}
.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)}
.subject-title{font-size:21px; margin:0; flex:1; min-width:200px}
.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}
/* ---------- 表单 ---------- */
.narrow{max-width:640px}
.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 input[type=text],.field input[type=email],.field input[type=tel],
.field input[type=password],.field textarea,.field select{
width:100%; border:1px solid var(--line-strong); border-radius:9px;
padding:9px 12px; font-size:15px; font-family:inherit; background:var(--card);
color:var(--fg); line-height:1.6;
}
.field textarea{resize:vertical; min-height:110px}
.field input:focus,.field textarea:focus,.field select:focus{
outline:none; border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-soft);
}
.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-pw{margin-top:6px}
.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; gap:8px; margin:18px 0 4px}
.filters input[type=text]{flex:1 1 220px; min-width:180px}
.filters select{max-width:160px}
@media (max-width:640px){
.grid2{grid-template-columns:1fr}
.filters input[type=text],.filters select{width:100%; max-width:none}
}