init: 我的博客项目

This commit is contained in:
Your Name
2026-09-09 19:30:18 +08:00
commit 76c241f032
34 changed files with 3420 additions and 0 deletions
+103
View File
@@ -0,0 +1,103 @@
.admin-body { }
.admin-layout { display:flex; align-items:flex-start; gap:24px; }
.admin-aside { position:sticky; top:88px; align-self:flex-start; width:224px; flex-shrink:0; }
.admin-main { flex:1; min-width:0; }
.admin-menu { padding:12px 10px; }
.admin-menu .menu-title { padding:6px 14px 8px; font-size:11px; letter-spacing:2px; color:var(--text-muted); }
.admin-menu a.menu-item {
display:block; padding:11px 14px; border-radius:12px; margin-bottom:3px;
color:var(--text-secondary); font-size:14px; transition:background .2s,color .2s;
}
.admin-menu a.menu-item:hover { background:var(--glass-bg-strong); color:var(--text-primary); }
.admin-menu a.menu-item.active { background:var(--text-primary); color:var(--bg-0); font-weight:600; }
.admin-menu .menu-sep { height:1px; background:var(--glass-border); margin:10px 6px; }
.admin-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:24px; flex-wrap:wrap; gap:12px; }
.admin-head h1 { font-size:24px; letter-spacing:.5px; }
.admin-head .sub { color:var(--text-muted); font-size:13px; margin-top:4px; }
.stat-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:16px; margin-bottom:26px; }
.stat-card { padding:22px 18px; text-align:center; position:relative; overflow:hidden; }
.stat-card .num { font-size:34px; font-weight:800; letter-spacing:-1px; }
.stat-card .label { color:var(--text-muted); font-size:13px; margin-top:6px; }
.stat-card .foot { font-size:12px; color:var(--text-muted); margin-top:8px; }
.table-wrap { overflow-x:auto; }
.admin-table th.title, .admin-table td.title { max-width:340px; overflow:hidden; text-overflow:ellipsis; }
.admin-table { width:100%; border-collapse:collapse; }
.admin-table th, .admin-table td { padding:11px 10px; text-align:left; border-bottom:1px solid var(--glass-border); font-size:14px; vertical-align:middle; white-space:nowrap; }
.admin-table th { font-weight:600; color:var(--text-secondary); white-space:nowrap; font-size:13px; }
.admin-table tbody tr { transition:background .15s; }
.admin-table tbody tr:hover { background:var(--glass-bg-strong); }
.admin-table tbody tr:last-child td { border-bottom:none; }
.admin-table .thumb { width:72px; height:44px; object-fit:cover; border-radius:8px; display:block; }
.admin-table .num-col { text-align:center; }
.actions a, .actions button { margin-right:10px; font-size:13px; color:var(--text-secondary); background:none; border:none; cursor:pointer; padding:0; }
.actions a:hover, .actions button:hover { color:var(--text-primary); }
.actions .danger { color:#c0392b; }
[data-theme="dark"] .actions .danger { color:#ff8a8a; }
.pagination { display:flex; gap:8px; align-items:center; margin-top:18px; flex-wrap:wrap; }
.pagination a, .pagination span { padding:7px 13px; border-radius:10px; font-size:13px; border:1px solid var(--glass-border); background:var(--glass-bg); color:var(--text-secondary); }
.pagination a:hover { color:var(--text-primary); }
.pagination .current { background:var(--text-primary); color:var(--bg-0); font-weight:600; border-color:var(--text-primary); }
.admin-form .field { margin-bottom:18px; }
.admin-form .field label { display:block; font-weight:600; margin-bottom:8px; font-size:14px; }
.admin-form .field .hint { font-size:12px; color:var(--text-muted); margin-top:6px; }
.admin-form .form-row { display:flex; gap:16px; }
.admin-form .form-row > div { flex:1; }
.admin-form textarea.input, .admin-form .input { width:100%; padding:11px 14px; border-radius:12px; border:1px solid var(--glass-border); background:var(--glass-bg); color:var(--text-primary); font-size:14px; outline:none; transition:.2s; font-family:inherit; }
.admin-form .input:focus { border-color:var(--text-primary); }
.admin-form textarea.input { resize:vertical; min-height:140px; line-height:1.7; }
.admin-form .input.code { font-family:ui-monospace,"Cascadia Code",Consolas,monospace; font-size:13px; }
.admin-form select.input { appearance:none; -webkit-appearance:none; }
.admin-form .btn-row { display:flex; gap:10px; margin-top:6px; }
.tag-check { display:inline-flex; align-items:center; gap:6px; margin:0 14px 10px 0; font-size:14px; color:var(--text-secondary); cursor:pointer; }
.tag-check input { width:16px; height:16px; accent-color:var(--text-primary); }
.msg { padding:13px 16px; border-radius:12px; margin-bottom:16px; background:var(--glass-bg-strong); border:1px solid var(--glass-border); font-size:14px; }
.msg.ok { border-color:rgba(34,139,34,.4); color:#2e7d32; }
[data-theme="dark"] .msg.ok { color:#8fd18f; }
.msg.err { border-color:rgba(192,57,43,.4); color:#c0392b; }
[data-theme="dark"] .msg.err { color:#ff8a8a; }
.card-title { display:flex; justify-content:space-between; align-items:center; margin-bottom:16px; }
.card-title h3 { font-size:16px; }
.text-muted { color:var(--text-muted); }
.empty { text-align:center; color:var(--text-muted); padding:56px 20px; font-size:14px; }
@media (max-width:900px){
.admin-aside { display:none; }
.admin-layout { display:block; }
}
.admin-main .card:hover { transform:none; }
.admin-main .card::after { display:none; }
.admin-main .card { margin-bottom:20px; }
.admin-head .head-right { display:flex; gap:10px; align-items:center; }
/* 后台输入框:清晰可见的边框与背景(浅色主题下白边框不可见) */
.admin-main .input,
.admin-main select.input,
.admin-main textarea.input {
width:100%; padding:11px 14px; border-radius:12px;
border:1px solid var(--input-border);
background:var(--glass-bg-strong);
color:var(--text-primary); font-size:14px; outline:none; transition:.2s; font-family:inherit;
}
.admin-main .input::placeholder { color:var(--text-muted); }
.admin-main .input:focus { border-color:var(--text-primary); box-shadow:0 0 0 3px var(--glass-border); }
.admin-main textarea.input { resize:vertical; min-height:140px; line-height:1.7; }
.admin-main .input.code { font-family:ui-monospace,"Cascadia Code",Consolas,monospace; font-size:13px; }
/* 自定义确认框 */
.modal-mask { position:fixed; inset:0; z-index:200; background:rgba(15,18,28,0.42); display:flex; align-items:center; justify-content:center; padding:24px; }
.modal { width:100%; max-width:360px; padding:28px; }
.modal .modal-title { font-size:17px; font-weight:700; margin-bottom:14px; }
.modal .modal-text { color:var(--text-secondary); font-size:14px; line-height:1.7; margin-bottom:24px; }
.modal .modal-actions { display:flex; justify-content:flex-end; gap:10px; }
+178
View File
@@ -0,0 +1,178 @@
:root {
--bg-0:#ffffff;
--bg-gradient: linear-gradient(160deg,#ffffff 0%,#f5f6fa 55%,#e9ecf3 100%);
--bg-glow: radial-gradient(circle at 50% -10%,rgba(255,255,255,0.35),transparent 55%);
--glass-bg: rgba(255,255,255,0.55);
--glass-bg-strong: rgba(255,255,255,0.8);
--glass-border: rgba(255,255,255,0.9);
--input-border: rgba(20,20,32,0.3);
--glass-highlight: rgba(255,255,255,1);
--glass-blur: 26px;
--glass-radius: 18px;
--text-primary:#141419; --text-secondary:rgba(20,20,32,0.62); --text-muted:rgba(20,20,32,0.42);
--shadow: 0 10px 36px rgba(31,45,84,0.12);
}
[data-theme="dark"] {
--bg-0:#0e0f13;
--bg-gradient: linear-gradient(160deg,#0e0f13 0%,#12141a 55%,#171a22 100%);
--bg-glow: radial-gradient(circle at 50% -10%,rgba(255,255,255,0.05),transparent 50%);
--glass-bg: rgba(255,255,255,0.06);
--glass-bg-strong: rgba(255,255,255,0.12);
--glass-border: rgba(255,255,255,0.14);
--input-border: rgba(255,255,255,0.35);
--glass-highlight: rgba(255,255,255,0.22);
--glass-blur: 26px;
--glass-radius: 18px;
--text-primary:#eef0f5; --text-secondary:rgba(255,255,255,0.66); --text-muted:rgba(255,255,255,0.4);
--shadow: 0 10px 36px rgba(0,0,0,0.5);
}
* { margin:0; padding:0; box-sizing:border-box; }
html { -webkit-text-size-adjust:100%; }
body { font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"PingFang SC","Microsoft YaHei",sans-serif; color:var(--text-primary); min-height:100vh; background:var(--bg-gradient); transition:background .4s; }
a { color:inherit; text-decoration:none; }
.bg { position:fixed; inset:0; z-index:-1; background:var(--bg-gradient); }
.bg::before { content:""; position:absolute; inset:-10%; background:var(--bg-glow); }
.glass { background:var(--glass-bg); backdrop-filter:blur(var(--glass-blur)) saturate(1.5); -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.5); border:1px solid var(--glass-border); border-radius:var(--glass-radius); box-shadow:inset 0 1px 0 var(--glass-highlight), var(--shadow); }
.glass-nav { position:fixed; top:0; left:0; right:0; z-index:50; display:flex; align-items:center; justify-content:space-between; padding:0 28px; height:64px; background:var(--glass-bg); backdrop-filter:blur(var(--glass-blur)) saturate(1.6); -webkit-backdrop-filter:blur(var(--glass-blur)) saturate(1.6); border-bottom:1px solid var(--glass-border); box-shadow:inset 0 1px 0 var(--glass-highlight); }
.nav-brand { font-weight:800; font-size:20px; letter-spacing:1px; color:var(--text-primary); }
.nav-links { display:flex; gap:6px; align-items:center; }
.nav-link { padding:8px 14px; border-radius:10px; color:var(--text-secondary); font-size:14px; transition:.2s; }
.nav-link:hover,.nav-link.active { background:var(--glass-bg-strong); color:var(--text-primary); }
.glass-btn { display:inline-block; padding:8px 16px; border-radius:12px; border:1px solid var(--glass-border); background:var(--glass-bg-strong); color:var(--text-primary); cursor:pointer; font-size:14px; transition:.2s; }
.glass-btn:hover { transform:translateY(-1px); }
.glass-btn.primary { background:var(--text-primary); color:var(--bg-0); border-color:transparent; }
.glass-chip { display:inline-block; padding:3px 12px; border-radius:999px; font-size:12px; background:var(--glass-bg); border:1px solid var(--glass-border); color:var(--text-secondary); }
.glass-input { width:100%; padding:12px 16px; border-radius:12px; border:1px solid var(--input-border); background:var(--glass-bg); color:var(--text-primary); font-size:14px; outline:none; transition:.2s; }
.glass-input:focus { border-color:var(--text-primary); box-shadow:0 0 0 3px var(--input-border); }
.glass-input::placeholder{ color:var(--text-muted); }
textarea.glass-input { resize:vertical; min-height:120px; font-family:inherit; }
.glass-select { padding:12px; border-radius:12px; border:1px solid var(--glass-border); background:var(--glass-bg); color:var(--text-primary); font-size:14px; outline:none; }
.theme-toggle { border:none; background:transparent; color:var(--text-secondary); font-size:14px; cursor:pointer; padding:8px 10px; }
.theme-toggle:hover { color:var(--text-primary); }
.container { max-width:1080px; margin:0 auto; padding:88px 24px 60px; }
.layout { display:grid; grid-template-columns:1fr 300px; gap:24px; }
@media (max-width:820px){ .layout{grid-template-columns:1fr;} .sidebar{display:none;} }
.sidebar { position:sticky; top:88px; align-self:start; display:flex; flex-direction:column; gap:20px; }
.side-panel { padding:20px; }
.side-panel h3 { font-size:15px; margin-bottom:14px; }
.chip-row { display:flex; flex-wrap:wrap; gap:8px; }
.chip-row .glass-chip { transition:.15s; }
.chip-row .glass-chip:hover { transform:translateY(-1px); color:var(--text-primary); }
.arch-item { display:flex; justify-content:space-between; padding:9px 0; border-bottom:1px dashed var(--glass-border); font-size:14px; color:var(--text-secondary); }
.arch-item:last-child{ border-bottom:none; }
.arch-item a:hover{ color:var(--text-primary); }
.hero { text-align:center; padding:40px 0 30px; }
.hero h1 { font-size:40px; font-weight:800; letter-spacing:2px; }
.hero h1 span{ color:var(--text-secondary); font-weight:300; }
.hero p { color:var(--text-secondary); margin-top:12px; font-size:15px; }
.search-row { max-width:520px; margin:18px auto 0; display:flex; gap:10px; }
.search-row .glass-btn{ flex-shrink:0; }
.card { padding:24px; margin-bottom:20px; display:block; transition:transform .25s, box-shadow .25s; position:relative; overflow:hidden; }
.card:hover { transform:translateY(-4px); }
.card-meta { display:flex; gap:12px; align-items:center; font-size:12px; color:var(--text-muted); margin-bottom:12px; }
.card h2 { font-size:22px; margin-bottom:10px; line-height:1.4; }
.card p { color:var(--text-secondary); line-height:1.7; font-size:15px; }
.card-foot { display:flex; justify-content:space-between; align-items:center; margin-top:16px; font-size:13px; color:var(--text-muted); }
.card.clickable { cursor:pointer; }
.pagination { display:flex; gap:8px; justify-content:center; margin-top:24px; }
.page-btn { padding:8px 14px; border-radius:10px; background:var(--glass-bg); border:1px solid var(--glass-border); color:var(--text-secondary); font-size:14px; }
.page-btn.active { background:var(--glass-bg-strong); color:var(--text-primary); }
.article-card { padding:32px; }
.article-card h1 { font-size:30px; line-height:1.4; margin-bottom:14px; }
.article-meta { display:flex; gap:16px; font-size:13px; color:var(--text-muted); margin-bottom:24px; flex-wrap:wrap; }
.article-body { line-height:1.9; font-size:16px; color:var(--text-primary); }
.article-body h2 { font-size:24px; margin:28px 0 14px; }
.article-body h3 { font-size:19px; margin:22px 0 10px; }
.article-body p { margin:14px 0; }
.article-body ul,.article-body ol { margin:14px 0 14px 24px; }
.article-body blockquote { border-left:3px solid var(--text-primary); padding:6px 16px; margin:14px 0; color:var(--text-secondary); font-style:italic; }
.article-body code { background:var(--glass-bg-strong); padding:2px 6px; border-radius:6px; font-size:0.9em; }
.article-body pre { background:rgba(0,0,0,0.05); padding:16px; border-radius:12px; overflow:auto; margin:14px 0; }
[data-theme="dark"] .article-body pre{ background:rgba(255,255,255,0.06);}
.article-body pre code { background:none; padding:0; }
.article-body img { max-width:100%; border-radius:12px; }
.comments { margin-top:24px; }
.comments h3 { margin-bottom:16px; }
.comment-item { padding:16px; margin-bottom:12px; }
.comment-item.reply { margin-left:36px; }
.comment-head { display:flex; gap:10px; align-items:center; font-size:13px; color:var(--text-muted); margin-bottom:8px; }
.comment-body { color:var(--text-secondary); line-height:1.7; font-size:14px; }
.comment-form .field { margin-bottom:14px; }
.login-wrap { max-width:380px; margin:0 auto; padding:40px 0; }
.login-box { padding:32px; }
.login-box h2 { margin-bottom:6px; font-size:22px; }
.login-box .sub { color:var(--text-muted); font-size:13px; margin-bottom:24px; }
.login-page { min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; }
.login-page .login-box { width:100%; max-width:380px; padding:38px; }
.login-page .login-brand { text-align:center; font-size:22px; font-weight:800; letter-spacing:1px; margin-bottom:26px; }
.login-page .theme-toggle { position:fixed; top:20px; right:24px; }
.login-page .login-back { text-align:center; margin-top:22px; font-size:13px; color:var(--text-muted); }
.login-page .login-back a { color:var(--text-secondary); }
.login-page .login-back a:hover { color:var(--text-primary); }
.field { margin-bottom:16px; }
.field label { display:block; font-size:13px; color:var(--text-secondary); margin-bottom:6px; }
.alert { padding:12px 16px; border-radius:10px; margin-bottom:16px; font-size:14px; background:var(--glass-bg-strong); border:1px solid var(--glass-border); color:var(--text-primary); }
.alert.error { border-color:rgba(180,60,60,0.4); color:rgba(180,60,60,1); }
[data-theme="dark"] .alert.error{ color:#ff8a8a; border-color:rgba(255,120,120,0.4);}
.page-head { margin-bottom:24px; }
.page-head h1 { font-size:26px; }
.page-head .desc { color:var(--text-muted); font-size:14px; margin-top:6px; }
.about-card { padding:32px; line-height:1.9; }
.about-card h2 { margin:20px 0 10px; }
.admin-head { display:flex; justify-content:space-between; align-items:center; margin-bottom:24px; flex-wrap:wrap; gap:12px; }
.admin-head h1 { font-size:24px; }
.stat-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:16px; margin-bottom:28px; }
.stat-card { padding:20px; text-align:center; }
.stat-card .num { font-size:32px; font-weight:800; }
.stat-card .label { color:var(--text-muted); font-size:13px; margin-top:4px; }
.table-wrap { overflow-x:auto; }
.glass-table { width:100%; border-collapse:collapse; font-size:14px; }
.glass-table th { text-align:left; padding:12px 14px; color:var(--text-muted); font-weight:600; font-size:13px; border-bottom:1px solid var(--glass-border); }
.glass-table td { padding:12px 14px; border-bottom:1px solid var(--glass-border); }
.glass-table tr:hover td { background:var(--glass-bg); }
.tag-badge { display:inline-block; padding:2px 10px; border-radius:999px; font-size:12px; background:var(--glass-bg); border:1px solid var(--glass-border); }
.actions a, .actions button { margin-right:8px; font-size:13px; color:var(--text-secondary); }
.actions a:hover, .actions button:hover{ color:var(--text-primary); }
.form-card { padding:24px; }
.form-card .field label { font-weight:600; }
.form-row { display:flex; gap:12px; }
.form-row > div { flex:1; }
.btn-danger { color:#c0392b; }
[data-theme="dark"] .btn-danger{ color:#ff8a8a;}
.footnote { text-align:center; color:var(--text-muted); font-size:12px; padding:20px 0 0; margin-top:20px; }
.msg { padding:12px 16px; border-radius:10px; margin-bottom:16px; background:var(--glass-bg-strong); border:1px solid var(--glass-border); font-size:14px; }
.side-panel a.nav-link {
display:block; padding:10px 12px; border-radius:8px; margin-bottom:4px;
color:var(--text-secondary); font-size:14px; text-decoration:none; transition:background .2s,color .2s;
}
.side-panel a.nav-link:hover { background:var(--glass-bg-strong); color:var(--text-primary); }
.side-panel a.nav-link.active { background:var(--glass-bg-strong); color:var(--text-primary); font-weight:600; }
.admin-table { width:100%; border-collapse:collapse; background:var(--glass-bg); border:1px solid var(--glass-border); border-radius:12px; overflow:hidden; }
.admin-table th, .admin-table td { padding:12px 14px; text-align:left; border-bottom:1px solid var(--glass-border); font-size:14px; }
.admin-table th { background:var(--glass-bg-strong); font-weight:600; color:var(--text-secondary); white-space:nowrap; }
.admin-table tr:last-child td { border-bottom:none; }
.admin-table tr:hover td { background:var(--glass-bg-strong); }
.admin-table .thumb { width:64px; height:40px; object-fit:cover; border-radius:6px; }
.text-muted { color:var(--text-muted); }
.input, .admin-table select, .admin-table input[type=text], .admin-table input[type=number] {
padding:8px 10px; border-radius:8px; border:1px solid var(--glass-border); background:var(--glass-bg); color:var(--text-primary); font-size:14px;
}
.admin-table input[type=checkbox]{ width:16px; height:16px; }
.pagination { display:flex; gap:8px; align-items:center; margin-top:20px; flex-wrap:wrap; }
.pagination a, .pagination span { padding:6px 12px; border-radius:8px; font-size:13px; border:1px solid var(--glass-border); background:var(--glass-bg); color:var(--text-secondary); }
.pagination a:hover { color:var(--text-primary); }
.pagination .current { background:var(--text-primary); color:var(--bg); font-weight:600; border-color:var(--text-primary); }
.badge-count { display:inline-block; min-width:20px; padding:0 6px; border-radius:999px; background:var(--glass-bg-strong); font-size:12px; text-align:center; }
+43
View File
@@ -0,0 +1,43 @@
(function () {
const btn = document.getElementById("themeBtn");
if (!btn) return;
function applyTheme(t) {
document.documentElement.setAttribute("data-theme", t);
btn.textContent = t === "dark" ? "浅色模式" : "深色模式";
try { localStorage.setItem("glass-theme", t); } catch(e) {}
}
function currentTheme() {
return document.documentElement.getAttribute("data-theme") || "light";
}
var saved = "light";
try { saved = localStorage.getItem("glass-theme") || "light"; } catch(e) {}
applyTheme(saved);
btn.addEventListener("click", function () {
applyTheme(currentTheme() === "dark" ? "light" : "dark");
});
})();
(function () {
var modal = document.getElementById("confirmModal");
if (!modal) return;
var text = document.getElementById("confirmText");
var ok = document.getElementById("confirmOk");
var cancel = document.getElementById("confirmCancel");
var target = null;
function open(msg, href) {
if (text) text.textContent = msg;
target = href;
modal.style.display = "flex";
}
function close() { modal.style.display = "none"; target = null; }
document.querySelectorAll("[data-confirm]").forEach(function (el) {
el.addEventListener("click", function (e) {
e.preventDefault();
open(el.getAttribute("data-confirm"), el.href);
});
});
if (ok) ok.addEventListener("click", function () { if (target) location.href = target; });
if (cancel) cancel.addEventListener("click", close);
modal.addEventListener("click", function (e) { if (e.target === modal) close(); });
document.addEventListener("keydown", function (e) { if (e.key === "Escape") close(); });
})();