diff --git a/Cargo.lock b/Cargo.lock
index fa82d82..f4e04f9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -214,6 +214,12 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+[[package]]
+name = "adler32"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
+
[[package]]
name = "ahash"
version = "0.7.8"
@@ -426,6 +432,15 @@ dependencies = [
"shlex",
]
+[[package]]
+name = "cedarwood"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d910bedd62c24733263d0bed247460853c9d22e8956bd4cd964302095e04e90"
+dependencies = [
+ "smallvec",
+]
+
[[package]]
name = "cfg-if"
version = "1.0.4"
@@ -606,6 +621,12 @@ dependencies = [
"hybrid-array",
]
+[[package]]
+name = "dary_heap"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b1e3a325bc115f096c8b77bbf027a7c2592230e70be2d985be950d3d5e60ebe"
+
[[package]]
name = "der"
version = "0.7.10"
@@ -877,6 +898,15 @@ dependencies = [
"slab",
]
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
[[package]]
name = "generic-array"
version = "0.14.7"
@@ -970,6 +1000,17 @@ dependencies = [
"allocator-api2",
]
+[[package]]
+name = "hashbrown"
+version = "0.16.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
+dependencies = [
+ "allocator-api2",
+ "equivalent",
+ "foldhash",
+]
+
[[package]]
name = "hashbrown"
version = "0.17.1"
@@ -1265,6 +1306,7 @@ dependencies = [
"chrono",
"config",
"image",
+ "jieba-rs",
"lazy_static",
"mimalloc",
"rand 0.8.7",
@@ -1286,6 +1328,39 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35a84fd5aa25fae5c0f4a33d9cac2ca017fc622cbd089be2229993514990f870"
+[[package]]
+name = "include-flate"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48f173716febb1ad596c16ea5637b5f1790ea32de8e627493ff82bc73b0876ce"
+dependencies = [
+ "include-flate-codegen",
+ "include-flate-compress",
+]
+
+[[package]]
+name = "include-flate-codegen"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a7875b62a72ad3f3203cdd8950d4cf9947db036030b974b8b37ceae90c8d8c0"
+dependencies = [
+ "include-flate-compress",
+ "proc-macro-error3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
+[[package]]
+name = "include-flate-compress"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44fbb9c5ccb9a5b67b4afa2974c27e5507ea1bf6d22828cef418e4dfaeca51dd"
+dependencies = [
+ "libflate",
+ "zstd",
+]
+
[[package]]
name = "indexmap"
version = "2.14.0"
@@ -1308,6 +1383,30 @@ version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
+[[package]]
+name = "jieba-macros"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c676b32a471d3cfae8dac2ad2f8334cd52e53377733cca8c1fb0a5062fec192"
+dependencies = [
+ "phf_codegen",
+]
+
+[[package]]
+name = "jieba-rs"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5dd552bbb95d578520ee68403bf8aaf0dbbb2ce55b0854d019f9350ad61040a"
+dependencies = [
+ "cedarwood",
+ "fxhash",
+ "include-flate",
+ "jieba-macros",
+ "lazy_static",
+ "phf",
+ "regex",
+]
+
[[package]]
name = "jobserver"
version = "0.1.35"
@@ -1367,6 +1466,30 @@ version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
+[[package]]
+name = "libflate"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cd96e993e5f3368b0cb8497dae6c860c22af8ff18388c61c6c0b86c58d86b5df"
+dependencies = [
+ "adler32",
+ "crc32fast",
+ "dary_heap",
+ "libflate_lz77",
+ "no_std_io2",
+]
+
+[[package]]
+name = "libflate_lz77"
+version = "2.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff7a10e427698aef6eef269482776debfef63384d30f13aad39a1a95e0e098fd"
+dependencies = [
+ "hashbrown 0.16.1",
+ "no_std_io2",
+ "rle-decode-fast",
+]
+
[[package]]
name = "libm"
version = "0.2.16"
@@ -1524,6 +1647,15 @@ dependencies = [
"windows-sys 0.61.2",
]
+[[package]]
+name = "no_std_io2"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003"
+dependencies = [
+ "memchr",
+]
+
[[package]]
name = "nom"
version = "7.1.3"
@@ -1702,6 +1834,44 @@ dependencies = [
"pest",
]
+[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_codegen"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared",
+ "rand 0.8.7",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
[[package]]
name = "pin-project-lite"
version = "0.2.17"
@@ -1778,6 +1948,28 @@ dependencies = [
"zerocopy",
]
+[[package]]
+name = "proc-macro-error-attr3"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34e4dd828515431dd6c4a030d26f7eaed7dd4778226e9d2bb968d65ca4ec3d4d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "proc-macro-error3"
+version = "3.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ee475e440453418ff1335189eddf7101ba502cd818ab7ae04209bc83aa925aa"
+dependencies = [
+ "proc-macro-error-attr3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
[[package]]
name = "proc-macro2"
version = "1.0.106"
@@ -1963,6 +2155,12 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "rle-decode-fast"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
+
[[package]]
name = "ron"
version = "0.7.1"
@@ -2220,6 +2418,12 @@ version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
+[[package]]
+name = "siphasher"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+
[[package]]
name = "slab"
version = "0.4.12"
diff --git a/assets/album.html b/assets/album.html
index 0ab87bd..6521e9f 100644
--- a/assets/album.html
+++ b/assets/album.html
@@ -15,10 +15,12 @@
返回首页
加载中...
-
@@ -38,13 +40,6 @@
来自: 相册名称
-
- 1 / 1
-
@@ -70,7 +65,19 @@
0 KB
+
+
+ 1 / 1
+
+
+
diff --git a/assets/css/album.css b/assets/css/album.css
index ad7ed89..7672fb4 100644
--- a/assets/css/album.css
+++ b/assets/css/album.css
@@ -88,25 +88,103 @@ body {
.album-info {
display: inline-flex;
align-items: center;
- gap: 16px;
- color: var(--text-light);
- font-size: 0.95rem;
- padding: 10px 20px;
- background: var(--bg-surface);
- border-radius: var(--radius-full);
- border: 1px solid var(--border-gray);
+ gap: 6px;
+ color: #475569;
+ font-size: 0.85rem;
+ font-weight: 500;
+ line-height: 1.2;
+ padding: 6px 14px;
+ background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
+ border-radius: 20px;
+ border: 1px solid #cbd5e1;
+ cursor: default;
+ user-select: none;
+ height: auto;
+ min-height: 0;
}
-.album-info i { color: var(--secondary-blue); }
+.album-info i { color: #64748b; }
-/* ============ 相册标签区(新:分类着色) ============ */
-.album-meta-tags {
+/* 照片数量 + 标签 合并到一行 */
+.album-header-row {
display: flex;
flex-wrap: wrap;
+ align-items: center;
justify-content: center;
+ gap: 12px 16px;
+ margin: 12px auto 24px;
+ max-width: 1100px;
+}
+
+.album-header-row .album-info {
+ margin: 0;
+ flex: 0 0 auto;
+ width: auto;
+ max-width: none;
+}
+
+/* ============ 相册标签区(简洁版:与照片数量同行) ============ */
+.album-header-row .album-meta-tags {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ gap: 8px;
+ margin: 0;
+ max-width: none;
+ min-width: 0;
+}
+
+/* 标签分组 */
+.tag-group {
+ margin-bottom: 14px;
+ background: var(--bg-surface);
+ border-radius: var(--radius-card);
+ border: 1px solid var(--border-gray);
+ padding: 12px 16px;
+ transition: all 0.2s ease;
+ box-shadow: var(--shadow-sm);
+}
+
+.tag-group:hover {
+ box-shadow: var(--shadow-md);
+ border-color: #cbd5e1;
+}
+
+.tag-group-header {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 10px;
+ padding-bottom: 8px;
+ border-bottom: 1px dashed var(--border-gray);
+ font-size: 0.85rem;
+ font-weight: 600;
+ color: var(--text-light);
+}
+
+.tag-group-header i {
+ font-size: 0.9rem;
+ color: var(--secondary-blue);
+}
+
+.tag-group-header span {
+ color: var(--text-light);
+}
+
+.tag-group-count {
+ margin-left: auto;
+ background: var(--bg-hover);
+ padding: 2px 8px;
+ border-radius: 10px;
+ font-size: 0.75rem;
+ font-weight: 600;
+ color: var(--text-muted);
+}
+
+.tag-group-chips {
+ display: flex;
+ flex-wrap: wrap;
gap: 8px;
- margin: 20px auto 32px;
- max-width: 900px;
}
.meta-chip {
@@ -114,13 +192,31 @@ body {
align-items: center;
gap: 6px;
padding: 6px 14px;
- border-radius: var(--radius-full);
+ border-radius: 20px;
font-size: 0.85rem;
font-weight: 500;
+ line-height: 1.2;
cursor: pointer;
transition: all 0.2s ease;
user-select: none;
border: 1px solid transparent;
+ position: relative;
+ overflow: hidden;
+}
+
+.meta-chip::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: -100%;
+ width: 100%;
+ height: 100%;
+ background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent);
+ transition: left 0.5s ease;
+}
+
+.meta-chip:hover::before {
+ left: 100%;
}
.meta-chip:hover {
@@ -130,13 +226,14 @@ body {
.meta-chip:active { transform: translateY(0); }
-.meta-chip i { font-size: 0.75rem; }
+.meta-chip i { font-size: 0.75rem; opacity: 0.9; }
/* 人物标签 */
.meta-chip-person {
- background: linear-gradient(135deg, rgba(139, 92, 246, 0.1) 0%, rgba(236, 72, 153, 0.1) 100%);
+ background: linear-gradient(135deg, rgba(139, 92, 246, 0.12) 0%, rgba(236, 72, 153, 0.12) 100%);
color: var(--accent-purple);
- border-color: rgba(139, 92, 246, 0.2);
+ border-color: rgba(139, 92, 246, 0.25);
+ font-weight: 600;
}
.meta-chip-person:hover {
@@ -147,54 +244,120 @@ body {
/* 分类标签(按类别着色) */
.meta-chip-tag-style {
- background: #f0f9ff;
+ background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
color: #0284c7;
border-color: #bae6fd;
}
-.meta-chip-tag-style:hover { background: #0284c7; color: #fff; border-color: #0284c7; }
+.meta-chip-tag-style:hover { background: linear-gradient(135deg, #0284c7 0%, #0369a1 100%); color: #fff; border-color: transparent; }
.meta-chip-tag-outfit {
- background: #fdf2f8;
+ background: linear-gradient(135deg, #fdf2f8 0%, #fce7f3 100%);
color: #db2777;
border-color: #fbcfe8;
}
-.meta-chip-tag-outfit:hover { background: #db2777; color: #fff; border-color: #db2777; }
+.meta-chip-tag-outfit:hover { background: linear-gradient(135deg, #db2777 0%, #be185d 100%); color: #fff; border-color: transparent; }
.meta-chip-tag-scene {
- background: #f0fdf4;
+ background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
color: #15803d;
border-color: #bbf7d0;
}
-.meta-chip-tag-scene:hover { background: #15803d; color: #fff; border-color: #15803d; }
+.meta-chip-tag-scene:hover { background: linear-gradient(135deg, #15803d 0%, #166534 100%); color: #fff; border-color: transparent; }
.meta-chip-tag-body {
- background: #fef3c7;
+ background: linear-gradient(135deg, #fef3c7 0%, #fde68a 100%);
color: #b45309;
border-color: #fde68a;
}
-.meta-chip-tag-body:hover { background: #b45309; color: #fff; border-color: #b45309; }
+.meta-chip-tag-body:hover { background: linear-gradient(135deg, #b45309 0%, #92400e 100%); color: #fff; border-color: transparent; }
.meta-chip-tag-mood {
- background: #faf5ff;
+ background: linear-gradient(135deg, #faf5ff 0%, #f3e8ff 100%);
color: #7c3aed;
border-color: #e9d5ff;
}
-.meta-chip-tag-mood:hover { background: #7c3aed; color: #fff; border-color: #7c3aed; }
+.meta-chip-tag-mood:hover { background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%); color: #fff; border-color: transparent; }
.meta-chip-tag-topic {
- background: #eff6ff;
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
color: #0369a1;
border-color: #bfdbfe;
}
-.meta-chip-tag-topic:hover { background: #0369a1; color: #fff; border-color: #0369a1; }
+.meta-chip-tag-topic:hover { background: linear-gradient(135deg, #0369a1 0%, #075985 100%); color: #fff; border-color: transparent; }
+
+/* jieba 提取的新分类 */
+.meta-chip-tag-noun {
+ background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
+ color: #1d4ed8;
+ border-color: #bfdbfe;
+}
+.meta-chip-tag-noun:hover { background: linear-gradient(135deg, #1d4ed8 0%, #1e40af 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-proper {
+ background: linear-gradient(135deg, #e0e7ff 0%, #c7d2fe 100%);
+ color: #4338ca;
+ border-color: #c7d2fe;
+}
+.meta-chip-tag-proper:hover { background: linear-gradient(135deg, #4338ca 0%, #3730a3 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-location {
+ background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
+ color: #047857;
+ border-color: #a7f3d0;
+}
+.meta-chip-tag-location:hover { background: linear-gradient(135deg, #047857 0%, #065f46 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-organization {
+ background: linear-gradient(135deg, #fef9c3 0%, #fef08a 100%);
+ color: #a16207;
+ border-color: #fde68a;
+}
+.meta-chip-tag-organization:hover { background: linear-gradient(135deg, #a16207 0%, #854d0e 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-noun_verb {
+ background: linear-gradient(135deg, #fce7f3 0%, #fbcfe8 100%);
+ color: #be185d;
+ border-color: #f9a8d4;
+}
+.meta-chip-tag-noun_verb:hover { background: linear-gradient(135deg, #be185d 0%, #9d174d 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-adj {
+ background: linear-gradient(135deg, #f3e8ff 0%, #e9d5ff 100%);
+ color: #6d28d9;
+ border-color: #ddd6fe;
+}
+.meta-chip-tag-adj:hover { background: linear-gradient(135deg, #6d28d9 0%, #5b21b6 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-verb {
+ background: linear-gradient(135deg, #fed7aa 0%, #fdba74 100%);
+ color: #c2410c;
+ border-color: #fed7aa;
+}
+.meta-chip-tag-verb:hover { background: linear-gradient(135deg, #c2410c 0%, #9a3412 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-chinese {
+ background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
+ color: #475569;
+ border-color: #cbd5e1;
+}
+.meta-chip-tag-chinese:hover { background: linear-gradient(135deg, #475569 0%, #334155 100%); color: #fff; border-color: transparent; }
+
+.meta-chip-tag-english {
+ background: linear-gradient(135deg, #f1f5f9 0%, #e2e8f0 100%);
+ color: #64748b;
+ border-color: #cbd5e1;
+}
+.meta-chip-tag-english:hover { background: linear-gradient(135deg, #64748b 0%, #475569 100%); color: #fff; border-color: transparent; }
/* 默认标签 */
+.meta-chip-tag-default,
.meta-chip-tag {
background: var(--bg-hover);
color: var(--text-light);
border-color: var(--border-gray);
}
-.meta-chip-tag:hover { background: var(--text-light); color: #fff; border-color: var(--text-light); }
+.meta-chip-tag-default:hover,
+.meta-chip-tag:hover { background: linear-gradient(135deg, #64748b 0%, #475569 100%); color: #fff; border-color: transparent; }
/* ============ 瀑布流布局(核心) ============ */
.images-grid {
@@ -214,7 +377,6 @@ body {
box-shadow: var(--shadow-sm);
background: var(--bg-surface);
transition: all 0.3s ease;
- cursor: pointer;
border: 1px solid var(--border-gray);
break-inside: avoid;
page-break-inside: avoid;
@@ -233,6 +395,7 @@ body {
display: block;
object-fit: contain;
transition: transform 0.4s ease;
+ cursor: pointer;
}
.image-item:hover img {
@@ -249,6 +412,7 @@ body {
align-items: center;
gap: 8px;
border-top: 1px solid var(--border-gray);
+ cursor: default;
}
.image-caption small {
@@ -368,7 +532,7 @@ body {
justify-content: center;
opacity: 0;
visibility: hidden;
- transition: all 0.3s ease;
+ transition: all 0.25s ease;
}
.preview-modal.active { opacity: 1; visibility: visible; }
@@ -377,44 +541,48 @@ body {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
- background: rgba(15, 23, 42, 0.9);
- backdrop-filter: blur(8px);
+ background: rgba(0, 0, 0, 0.92);
+ backdrop-filter: blur(4px);
}
.preview-container {
position: relative;
- background: var(--bg-surface);
- border-radius: var(--radius-lg);
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
- max-width: 92vw;
- max-height: 90vh;
- width: 1200px;
- height: 800px;
+ width: 100vw;
+ height: 100vh;
+ max-width: 100vw;
+ max-height: 100vh;
display: flex;
flex-direction: column;
- transform: scale(0.92);
- transition: transform 0.3s ease;
+ background: transparent;
+ border-radius: 0;
+ box-shadow: none;
+ transform: scale(1);
}
.preview-modal.active .preview-container { transform: scale(1); }
+/* 顶部栏 - 浮在图片上方 */
.preview-header {
+ position: absolute;
+ top: 0; left: 0; right: 0;
+ z-index: 10;
display: flex;
justify-content: space-between;
align-items: center;
- padding: 16px 20px;
- border-bottom: 1px solid var(--border-gray);
+ padding: 16px 24px;
+ background: linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, transparent 100%);
flex-shrink: 0;
+ border: none;
}
.preview-title h3 {
- font-size: 1.1rem;
+ font-size: 1rem;
font-weight: 600;
- color: var(--text-dark);
+ color: #f1f5f9;
margin: 0 0 4px 0;
}
-.preview-info { font-size: 0.85rem; color: var(--text-light); }
+.preview-info { font-size: 0.8rem; color: #94a3b8; }
.preview-actions {
display: flex;
@@ -423,51 +591,60 @@ body {
}
.preview-nav {
- width: 36px; height: 36px;
- border: 1px solid var(--border-gray);
- border-radius: var(--radius);
- background: var(--bg-surface);
- color: var(--text-dark);
+ width: 40px; height: 40px;
+ border: 1px solid rgba(255,255,255,0.15);
+ border-radius: 50%;
+ background: rgba(255,255,255,0.08);
+ color: #f1f5f9;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
+ backdrop-filter: blur(10px);
}
.preview-nav:hover:not(:disabled) {
- background: var(--bg-hover);
- border-color: var(--secondary-blue);
- color: var(--secondary-blue);
+ background: rgba(255,255,255,0.2);
+ border-color: rgba(255,255,255,0.3);
+ color: #fff;
}
-.preview-nav:disabled { opacity: 0.4; cursor: not-allowed; }
+.preview-nav:disabled { opacity: 0.3; cursor: not-allowed; }
-.preview-counter { font-size: 0.85rem; color: var(--text-light); font-weight: 500; }
+.preview-counter {
+ font-size: 0.9rem;
+ color: #cbd5e1;
+ font-weight: 500;
+ padding: 0 4px;
+}
.preview-close {
- width: 36px; height: 36px;
- border: none;
- border-radius: var(--radius);
- background: var(--bg-hover);
- color: var(--text-dark);
+ width: 40px; height: 40px;
+ border: 1px solid rgba(255,255,255,0.15);
+ border-radius: 50%;
+ background: rgba(255,255,255,0.08);
+ color: #f1f5f9;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
+ backdrop-filter: blur(10px);
}
-.preview-close:hover { background: #ef4444; color: #fff; }
+.preview-close:hover { background: rgba(239, 68, 68, 0.8); color: #fff; border-color: rgba(239, 68, 68, 0.6); }
+/* 图片内容区 - 占满全屏 */
.preview-content {
- flex: 1;
- padding: 0;
+ position: absolute;
+ top: 0; left: 0; right: 0; bottom: 0;
+ padding: 60px 80px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
- background: #0f172a;
+ background: transparent;
}
.preview-image-container {
@@ -482,8 +659,12 @@ body {
.preview-image {
max-width: 100%;
max-height: 100%;
+ width: auto;
+ height: auto;
object-fit: contain;
- transition: opacity 0.3s ease;
+ transition: opacity 0.3s ease, transform 0.3s ease;
+ box-shadow: 0 25px 80px rgba(0, 0, 0, 0.5);
+ border-radius: 4px;
}
.preview-loading {
@@ -494,54 +675,107 @@ body {
flex-direction: column;
align-items: center;
gap: 8px;
- color: var(--text-light);
+ color: #94a3b8;
}
-.preview-loading i { font-size: 1.8rem; color: var(--secondary-blue); }
+.preview-loading i { font-size: 2rem; color: #3b82f6; }
+/* 底部栏 - 浮在图片上方 */
.preview-footer {
+ position: absolute;
+ bottom: 0; left: 0; right: 0;
+ z-index: 10;
display: flex;
justify-content: space-between;
align-items: center;
- padding: 12px 20px;
- border-top: 1px solid var(--border-gray);
+ gap: 20px;
+ padding: 16px 24px;
+ background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, transparent 100%);
flex-shrink: 0;
+ border: none;
}
-.preview-meta { display: flex; gap: 16px; }
+.preview-meta { display: flex; gap: 16px; flex: 1; }
.preview-meta .meta-item {
display: flex;
align-items: center;
gap: 6px;
- font-size: 0.85rem;
- color: var(--text-light);
+ font-size: 0.8rem;
+ color: #cbd5e1;
}
-.preview-controls { display: flex; gap: 10px; }
+/* 底部居中的切换控制栏 */
+.preview-center-controls {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ flex: 1;
+ justify-content: center;
+}
+
+.preview-center-controls .preview-nav {
+ width: 40px;
+ height: 40px;
+ border: 1px solid rgba(255,255,255,0.2);
+ border-radius: 50%;
+ background: rgba(255,255,255,0.1);
+ color: #f1f5f9;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: all 0.2s ease;
+ backdrop-filter: blur(10px);
+ font-size: 0.9rem;
+}
+
+.preview-center-controls .preview-nav:hover:not(:disabled) {
+ background: rgba(255,255,255,0.25);
+ border-color: rgba(255,255,255,0.4);
+ transform: scale(1.08);
+}
+
+.preview-center-controls .preview-nav:disabled {
+ opacity: 0.3;
+ cursor: not-allowed;
+}
+
+.preview-center-controls .preview-counter {
+ font-size: 0.9rem;
+ color: #e2e8f0;
+ font-weight: 500;
+ min-width: 60px;
+ text-align: center;
+}
+
+.preview-controls { display: flex; gap: 10px; flex: 1; justify-content: flex-end; }
.preview-action {
- padding: 7px 14px;
- border: 1px solid var(--border-gray);
- border-radius: var(--radius);
- background: var(--bg-surface);
- color: var(--text-dark);
+ padding: 8px 16px;
+ border: 1px solid rgba(255,255,255,0.15);
+ border-radius: 20px;
+ background: rgba(255,255,255,0.08);
+ color: #f1f5f9;
cursor: pointer;
- font-size: 0.85rem;
+ font-size: 0.8rem;
font-weight: 500;
transition: all 0.2s ease;
display: flex;
align-items: center;
gap: 6px;
+ backdrop-filter: blur(10px);
}
-.preview-action:hover { background: var(--bg-hover); }
+.preview-action:hover { background: rgba(255,255,255,0.2); }
-.preview-remove { border-color: #fecaca; color: #dc2626; }
-.preview-remove:hover { background: #fef2f2; border-color: #fca5a5; }
+.preview-action-close:hover {
+ background: rgba(239, 68, 68, 0.7);
+ border-color: rgba(239, 68, 68, 0.5);
+}
-.preview-action.favorited { border-color: #fbcfe8; color: #ec4899; background: #fdf2f8; }
-.preview-action.favorited:hover { background: #fce7f3; border-color: #f9a8d4; }
+.preview-action.favorited { border-color: rgba(236, 72, 153, 0.5); color: #f9a8d4; background: rgba(236, 72, 153, 0.15); }
+.preview-action.favorited:hover { background: rgba(236, 72, 153, 0.25); }
/* 暗色模式 */
@media (prefers-color-scheme: dark) {
@@ -554,6 +788,15 @@ body {
--text-light: #cbd5e1;
--text-muted: #94a3b8;
}
- .preview-container { background: var(--bg-surface); }
- .preview-nav, .preview-close, .preview-action { background: var(--bg-hover); color: var(--text-dark); border-color: var(--border-gray); }
+}
+
+/* 移动端适配 */
+@media (max-width: 768px) {
+ .preview-content { padding: 40px 10px 70px; }
+ .preview-header, .preview-footer { padding: 12px 16px; }
+ .preview-footer { flex-wrap: wrap; gap: 12px; }
+ .preview-meta { order: 2; justify-content: center; }
+ .preview-center-controls { order: 1; width: 100%; }
+ .preview-controls { order: 3; justify-content: center; }
+ .preview-center-controls .preview-nav { width: 36px; height: 36px; }
}
diff --git a/assets/css/style.css b/assets/css/style.css
index df13b87..9d90491 100644
--- a/assets/css/style.css
+++ b/assets/css/style.css
@@ -107,30 +107,56 @@ input { font-family: inherit; }
.sidebar.collapsed .brand-text,
.sidebar.collapsed .nav-item span,
.sidebar.collapsed .sidebar-section-title span,
+.sidebar.collapsed .sidebar-section-title .section-arrow,
.sidebar.collapsed .sidebar-tags,
-.sidebar.collapsed .collapse-btn span {
+.sidebar.collapsed .sidebar-people,
+.sidebar.collapsed .sidebar-section-content,
+.sidebar.collapsed .sidebar-divider {
opacity: 0;
pointer-events: none;
+ display: none;
+}
+
+.sidebar.collapsed .sidebar-section {
+ padding: var(--spacer-md) 0;
+ gap: var(--spacer-xs);
}
.sidebar.collapsed .sidebar-section-title {
justify-content: center;
+ padding: var(--spacer-sm) 0;
+ margin-bottom: 0;
+}
+
+.sidebar.collapsed .sidebar-section-group {
+ margin-bottom: var(--spacer-sm);
}
.sidebar.collapsed .nav-item {
justify-content: center;
padding-left: 0;
padding-right: 0;
+ margin: 0 var(--spacer-xs);
+}
+
+.sidebar.collapsed .sidebar-brand {
+ padding: var(--spacer-lg) 0;
+ justify-content: center;
}
.sidebar.collapsed .collapse-btn {
justify-content: center;
+ padding: var(--spacer-md) 0;
}
.sidebar.collapsed .collapse-btn i {
transform: rotate(180deg);
}
+.sidebar.collapsed .sidebar-nav {
+ padding: var(--spacer-md) var(--spacer-xs);
+}
+
/* 品牌 Logo */
.sidebar-brand {
display: flex;
@@ -228,6 +254,7 @@ input { font-family: inherit; }
display: flex;
flex-direction: column;
min-height: 0;
+ gap: var(--spacer-sm);
}
.sidebar-section::-webkit-scrollbar {
@@ -238,6 +265,12 @@ input { font-family: inherit; }
border-radius: 2px;
}
+/* 可折叠区块组 */
+.sidebar-section-group {
+ display: flex;
+ flex-direction: column;
+}
+
.sidebar-section-title {
display: flex;
align-items: center;
@@ -251,7 +284,49 @@ input { font-family: inherit; }
margin-bottom: var(--spacer-sm);
}
-.sidebar-section-title i {
+.sidebar-section-title.collapsible {
+ cursor: pointer;
+ border-radius: var(--radius);
+ transition: background var(--transition-fast);
+ user-select: none;
+}
+
+.sidebar-section-title.collapsible:hover {
+ background: var(--bg-hover);
+ color: var(--text-light);
+}
+
+.section-arrow {
+ margin-left: auto;
+ font-size: 0.7rem;
+ transition: transform var(--transition-base);
+ opacity: 0.6;
+}
+
+.sidebar-section-group.collapsed .section-arrow {
+ transform: rotate(-90deg);
+}
+
+.sidebar-section-content {
+ overflow: hidden;
+ max-height: 600px;
+ transition: max-height 0.28s cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 0.2s ease,
+ margin 0.2s ease;
+ opacity: 1;
+ margin-bottom: var(--spacer-sm);
+}
+
+.sidebar-section-group.collapsed .sidebar-section-content {
+ max-height: 0;
+ opacity: 0;
+ margin-bottom: 0;
+ transition: max-height 0.2s cubic-bezier(0.4, 0, 0.2, 1),
+ opacity 0.15s ease,
+ margin 0.15s ease;
+}
+
+.sidebar-section-title i:first-child {
width: 20px;
text-align: center;
font-size: 0.85rem;
@@ -309,24 +384,95 @@ input { font-family: inherit; }
color: var(--white);
}
+/* 侧边栏人物列表 */
+.sidebar-people {
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacer-xs);
+ transition: opacity var(--transition-base);
+}
+
+.sidebar-person {
+ display: flex;
+ align-items: center;
+ gap: var(--spacer-sm);
+ padding: var(--spacer-sm) var(--spacer-lg);
+ border-radius: var(--radius);
+ cursor: pointer;
+ transition: all var(--transition-fast);
+ font-size: 0.9rem;
+ color: var(--text-light);
+}
+
+.sidebar-person:hover {
+ background: var(--bg-hover);
+ color: var(--text-dark);
+}
+
+.sidebar-person.active {
+ background: rgba(139, 92, 246, 0.1);
+ color: var(--accent-purple);
+ font-weight: 500;
+}
+
+.sidebar-person-avatar {
+ width: 28px;
+ height: 28px;
+ border-radius: 50%;
+ background: #6366f1;
+ color: var(--white);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 0.8rem;
+ font-weight: 600;
+ flex-shrink: 0;
+}
+
+.sidebar-person-info {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+ min-width: 0;
+}
+
+.sidebar-person-name {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-size: 0.9rem;
+}
+
+.sidebar-person-count {
+ font-size: 0.75rem;
+ color: var(--text-muted);
+}
+
+.sidebar-person.active .sidebar-person-count {
+ color: var(--accent-purple);
+ opacity: 0.8;
+}
+
/* 侧边栏底部 */
.sidebar-footer {
padding: var(--spacer-md);
border-top: 1px solid var(--border-gray);
flex-shrink: 0;
+ margin-top: auto;
}
.collapse-btn {
display: flex;
align-items: center;
- gap: var(--spacer-md);
+ justify-content: center;
width: 100%;
- padding: var(--spacer-md) var(--spacer-lg);
+ padding: var(--spacer-md);
border-radius: var(--radius);
color: var(--text-light);
- font-size: 0.9rem;
+ font-size: 1rem;
font-weight: 500;
transition: all var(--transition-fast);
+ cursor: pointer;
}
.collapse-btn:hover {
@@ -338,12 +484,6 @@ input { font-family: inherit; }
width: 20px;
text-align: center;
transition: transform var(--transition-base);
- flex-shrink: 0;
-}
-
-.collapse-btn span {
- transition: opacity var(--transition-base);
- white-space: nowrap;
}
/* ============ 主内容区 ============ */
diff --git a/assets/index.html b/assets/index.html
index f4f5421..c14d769 100644
--- a/assets/index.html
+++ b/assets/index.html
@@ -37,22 +37,38 @@
+
+
+
-