Files
backend_v2/internal/handler/assets/admin.css
toom1996 c3a6baa419 update
2026-09-22 21:40:04 +08:00

432 lines
12 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.

/* ============================================================================
* 管理后台统一样式(合并原先散在 14 个内联模板里的 12 份重复 <style>)。
*
* 设计基调沿用原后台:黑白、直角感、系统字体、无外部依赖。
* 统一后只此一份,改样式不必再逐页改 14 处。
*
* 约定:
* 1) 布局三件套 —— body(页面底色)/ .bar(顶部导航)/ .main(内容容器)
* 2) 组件化 —— .btn / .badge / .card / .cell / .pager / .flash 等按语义命名,
* 页面只写结构,不再写内联 style
* 3) 缩略图统一 2:3 —— 与站内图片素材比例一致(后端素材为 240×360 / 720×1080)
* ==========================================================================*/
/* ---------- 基础 ---------- */
* { box-sizing: border-box; }
/* 让 hidden 属性始终生效:下面给 .batchbar/.flash/.chk 设了 display,
作者样式会盖过浏览器默认的 [hidden]{display:none},故这里强制抬高。 */
[hidden] { display: none !important; }
body {
margin: 0;
font: 14px/1.6 system-ui, -apple-system, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
color: #111;
background: #f4f4f5;
-webkit-font-smoothing: antialiased;
}
h1 { font-size: 20px; margin: 0 0 4px; }
h2 { font-size: 15px; margin: 26px 0 10px; color: #333; }
a { color: #111; }
a.view { text-decoration: underline; }
.muted { color: #777; }
code {
font-family: ui-monospace, Menlo, Consolas, monospace;
font-size: 12px;
background: #f6f6f7;
padding: 1px 5px;
border-radius: 4px;
}
.break { word-break: break-all; }
:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
/* ---------- 顶部导航 ---------- */
.bar {
background: #111;
color: #fff;
padding: 10px 24px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 16px;
flex-wrap: wrap;
position: sticky;
top: 0;
z-index: 20;
}
.bar a { color: #fff; text-decoration: none; }
.bar-title { font-weight: 600; white-space: nowrap; }
.bar-nav { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.bar-nav a {
padding: 4px 9px;
border-radius: 6px;
font-size: 13px;
opacity: .78;
transition: background .15s, opacity .15s;
white-space: nowrap;
}
.bar-nav a:hover { opacity: 1; background: rgba(255, 255, 255, .14); }
.bar-nav a.on { opacity: 1; background: rgba(255, 255, 255, .2); }
.bar-nav .sep { width: 1px; height: 14px; background: rgba(255, 255, 255, .25); margin: 0 6px; }
.bar-badge {
display: inline-block;
min-width: 16px;
padding: 0 5px;
margin-left: 5px;
border-radius: 9px;
background: #f59e0b;
color: #111;
font-size: 11px;
font-weight: 700;
text-align: center;
vertical-align: 1px;
}
/* ---------- 内容容器 ---------- */
.main { max-width: 1100px; margin: 24px auto 60px; padding: 0 24px; }
.main.narrow { max-width: 620px; margin-top: 32px; }
.main.mid { max-width: 900px; }
/* 登录页固定宽卡片 */
.wrap {
max-width: 360px;
margin: 80px auto;
background: #fff;
padding: 28px 28px 32px;
border: 1px solid #e2e2e3;
border-radius: 10px;
}
.wrap h1 { margin-bottom: 18px; }
.wrap button { width: 100%; margin-top: 18px; }
/* ---------- 提示条 ---------- */
.flash {
padding: 10px 14px;
border-radius: 8px;
margin: 14px 0;
font-size: 13px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
}
.flash.ok { background: #e6f7ec; border: 1px solid #a9dcbd; color: #1a7f43; }
.flash.err, .err { color: #c0392b; }
.flash.err { background: #fdeaea; border: 1px solid #f0b7b3; }
/* 收起按钮(提示条 / 顶部提示里的小 ✕):必须是「无底无边」的小图标,
否则会继承下面 button 的黑底样式,变成一个突兀的黑方块。 */
.hint .x, .flash .x {
background: none;
border: 0;
color: inherit;
cursor: pointer;
font-size: 15px;
line-height: 1;
padding: 2px 6px;
margin-left: auto;
}
/* hint 是 sticky(已定位),收起按钮绝对定位到右上角,不参与文字排版 */
.hint { padding-right: 34px; }
.hint .x { position: absolute; top: 6px; right: 8px; }
.hint {
position: sticky;
top: 52px;
background: #fffbe6;
border: 1px solid #f5e08a;
color: #7a5b00;
padding: 8px 12px;
border-radius: 6px;
margin: 12px 0;
font-size: 13px;
z-index: 10;
}
/* ---------- 表单 ---------- */
label { display: block; margin: 14px 0 4px; color: #555; }
input, textarea, select {
width: 100%;
padding: 9px 10px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
font-family: inherit;
background: #fff;
}
input[type="checkbox"], input[type="radio"] { width: auto; padding: 0; }
textarea { min-height: 72px; }
.row { display: flex; gap: 14px; }
.row > div { flex: 1; min-width: 0; }
button {
padding: 9px 16px;
background: #111;
color: #fff;
border: 1px solid #111;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-family: inherit;
}
button:hover { opacity: .88; }
button.reject, button.danger { background: #c0392b; border-color: #c0392b; }
button.ghost { background: #fff; color: #111; border-color: #ccc; }
button.retry {
font-size: 12px;
padding: 4px 10px;
border-color: #c0392b;
color: #c0392b;
background: #fff;
}
button.retry:hover { background: #c0392b; color: #fff; opacity: 1; }
button:disabled { opacity: .45; cursor: default; }
/* ---------- 工具栏 / 筛选 ---------- */
.toolbar {
display: flex;
gap: 10px;
flex-wrap: wrap;
align-items: center;
margin: 16px 0;
}
.toolbar input, .toolbar select { width: auto; padding: 8px 10px; }
.toolbar a { color: #555; text-decoration: none; font-size: 13px; }
.tabs a, .kinds a {
display: inline-block;
margin: 0 8px 8px 0;
color: #111;
text-decoration: none;
font-size: 13px;
padding: 4px 9px;
border-radius: 6px;
border: 1px solid transparent;
}
.kinds a { border-color: #ddd; }
.tabs a.on, .kinds a.on { background: #111; color: #fff; border-color: #111; }
.idx { line-height: 2.2; }
.idx a { margin-right: 8px; text-decoration: none; font-size: 13px; }
.idx a.on { font-weight: 700; text-decoration: underline; }
/* ---------- 表格 ---------- */
.table-wrap { overflow-x: auto; }
table {
width: 100%;
border-collapse: collapse;
background: #fff;
margin-top: 12px;
border: 1px solid #e6e6e7;
border-radius: 8px;
}
th, td {
text-align: left;
padding: 10px 12px;
border-bottom: 1px solid #eee;
font-size: 13px;
vertical-align: top;
}
th { background: #fafafa; color: #555; font-weight: 600; white-space: nowrap; }
tbody tr:hover { background: #fbfbfc; }
tbody tr:last-child td { border-bottom: 0; }
/* ---------- 徽标 ---------- */
.badge {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
white-space: nowrap;
}
.badge.pending { background: #fff4e0; color: #a85b00; }
.badge.processing { background: #eef2ff; color: #3b4bb5; }
.badge.approved, .badge.done { background: #e6f7ec; color: #1a7f43; }
.badge.rejected, .badge.failed { background: #fdeaea; color: #c0392b; }
.badge.dup { background: #f3e8ff; color: #6b21a8; }
.badge.free { background: #eef2ff; color: #3b4bb5; }
.badge.vip { background: #fff4e0; color: #a85b00; }
.kind {
display: inline-block;
font-size: 12px;
padding: 1px 7px;
border-radius: 10px;
background: #eef2ff;
color: #3b4bb5;
}
.kind.street { background: #eafaf0; color: #1a7f43; }
.down { display: inline-block; padding: 2px 8px; background: #fdeaea; color: #c0392b; border-radius: 10px; font-size: 12px; }
/* ---------- 卡片(首页入口) ---------- */
.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px; margin-top: 20px; }
.card {
background: #fff;
border: 1px solid #e2e2e3;
border-radius: 10px;
padding: 18px;
text-decoration: none;
color: #111;
display: block;
transition: border-color .15s, transform .15s;
}
.card:hover { border-color: #111; transform: translateY(-1px); }
.card .t { font-size: 15px; font-weight: 600; }
.card .d { color: #777; font-size: 13px; margin-top: 6px; }
.chips { margin-top: 10px; }
.chip { display: inline-block; background: #111; color: #fff; font-size: 12px; padding: 3px 9px; border-radius: 10px; margin: 0 6px 6px 0; }
/* ---------- 图片网格(审核 / 图集) ---------- */
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
gap: 12px;
margin-top: 14px;
}
.cell {
background: #fff;
border: 1px solid #e6e6e7;
border-radius: 8px;
overflow: hidden;
display: flex;
flex-direction: column;
}
.cell.det { background: #f8faff; border-color: #c7d2fe; }
.cell.selected { border-color: #111; box-shadow: 0 0 0 2px rgba(0, 0, 0, .12); }
/* 缩略图统一 2:3,与站内素材比例一致;点击看大图由 admin.js 接管 */
.cell .thumb {
position: relative;
display: block;
width: 100%;
padding: 0;
border: 0;
border-radius: 0;
background: #f1f1f2;
cursor: zoom-in;
}
.cell .thumb img, .cell > img { width: 100%; display: block; aspect-ratio: 2 / 3; object-fit: cover; }
.cell > img { cursor: zoom-in; }
.cell .thumb::after {
content: "点击看大图";
position: absolute;
right: 6px;
bottom: 6px;
padding: 2px 6px;
border-radius: 4px;
background: rgba(0, 0, 0, .62);
color: #fff;
font-size: 11px;
opacity: 0;
transition: opacity .15s;
}
.cell .thumb:hover::after { opacity: 1; }
.cell .role { display: block; padding: 6px 8px 0; font-size: 12px; color: #1a7f43; }
.cell.det .role { color: #3b4bb5; }
.cell .nm { display: block; padding: 2px 8px 6px; font-size: 12px; color: #555; word-break: break-all; }
.cell .acts { padding: 8px; display: flex; flex-wrap: wrap; gap: 6px; margin-top: auto; }
.cell .acts button, .cell .acts .btn { margin: 0; flex: 1 1 auto; padding: 7px 8px; font-size: 13px; }
.btn {
display: inline-block;
flex: 1 1 auto;
margin: 0;
padding: 7px 10px;
background: #fff;
color: #111;
border: 1px solid #ccc;
border-radius: 6px;
text-decoration: none;
font-size: 13px;
text-align: center;
cursor: pointer;
}
.btn:hover { border-color: #111; }
.chk {
display: flex;
align-items: center;
gap: 5px;
flex: 1 1 auto;
font-size: 12px;
color: #333;
white-space: nowrap;
cursor: pointer;
margin: 0;
padding: 5px 6px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
}
.chk:hover { border-color: #111; }
.chk input { margin: 0; }
/* ---------- 底部批量操作条 ---------- */
.batchbar {
position: sticky;
bottom: 0;
background: #fff;
border: 1px solid #e6e6e7;
border-radius: 8px;
padding: 10px 12px;
margin-top: 18px;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
box-shadow: 0 -2px 12px rgba(0, 0, 0, .06);
z-index: 15;
}
.batchbar button { margin: 0; }
.batchbar .spacer { flex: 1; }
/* ---------- 分页 ---------- */
.pager { margin: 18px 0; display: flex; gap: 12px; align-items: center; }
.pager a { padding: 7px 14px; border: 1px solid #ccc; border-radius: 6px; text-decoration: none; background: #fff; }
.pager a:hover { border-color: #111; }
.pager a.off { color: #bbb; border-color: #eee; pointer-events: none; }
/* ---------- 大图查看层(admin.js 用) ---------- */
.lightbox {
position: fixed;
inset: 0;
z-index: 100;
background: rgba(0, 0, 0, .88);
display: flex;
align-items: center;
justify-content: center;
padding: 32px;
}
.lightbox[hidden] { display: none; }
.lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lightbox .lb-close,
.lightbox .lb-prev,
.lightbox .lb-next {
position: absolute;
background: rgba(255, 255, 255, .92);
color: #111;
border: 0;
border-radius: 8px;
width: 40px;
height: 40px;
font-size: 18px;
line-height: 1;
cursor: pointer;
}
.lightbox .lb-close { top: 18px; right: 18px; }
.lightbox .lb-prev { left: 18px; top: 50%; transform: translateY(-50%); }
.lightbox .lb-next { right: 18px; top: 50%; transform: translateY(-50%); }
.lightbox .lb-cap {
position: absolute;
left: 0;
right: 0;
bottom: 16px;
text-align: center;
color: #eee;
font-size: 12px;
}
/* ---------- 窄屏 ---------- */
@media (max-width: 720px) {
.bar { padding: 10px 14px; }
.bar-title { font-size: 13px; }
.main { padding: 0 14px; margin-top: 16px; }
.row { flex-direction: column; gap: 0; }
.grid { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
}