@windcoder/astro-theme-orchid 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/README.md +118 -2
  2. package/package.json +70 -5
  3. package/src/components/AlbumCard.astro +73 -0
  4. package/src/components/Analytics.astro +22 -0
  5. package/src/components/BaseLayout.astro +188 -0
  6. package/src/components/Calendar.astro +379 -0
  7. package/src/components/CategoryBar.astro +74 -0
  8. package/src/components/Comment.astro +48 -0
  9. package/src/components/EncryptedContent.astro +42 -0
  10. package/src/components/Footer.astro +31 -0
  11. package/src/components/Header.astro +153 -0
  12. package/src/components/License.astro +29 -0
  13. package/src/components/Live2DWidget.astro +262 -0
  14. package/src/components/MusicPlayer.astro +940 -0
  15. package/src/components/OutdatedCard.astro +53 -0
  16. package/src/components/Pagination.astro +94 -0
  17. package/src/components/PhotoCard.astro +22 -0
  18. package/src/components/PostCard.astro +89 -0
  19. package/src/components/PostNav.astro +40 -0
  20. package/src/components/RecommendedPost.astro +166 -0
  21. package/src/components/SakuraEffect.astro +152 -0
  22. package/src/components/Sidebar.astro +334 -0
  23. package/src/components/Toc.astro +27 -0
  24. package/src/components/analytics/GoogleAnalytics.astro +22 -0
  25. package/src/components/analytics/La51Analytics.astro +52 -0
  26. package/src/components/analytics/MicrosoftClarity.astro +18 -0
  27. package/src/components/analytics/UmamiAnalytics.astro +86 -0
  28. package/src/components/comments/Artalk.astro +51 -0
  29. package/src/components/comments/Disqus.astro +43 -0
  30. package/src/components/comments/Giscus.astro +50 -0
  31. package/src/components/comments/Twikoo.astro +65 -0
  32. package/src/components/comments/Waline.astro +36 -0
  33. package/src/i18n/en.ts +164 -0
  34. package/src/i18n/index.ts +18 -0
  35. package/src/i18n/resolve.ts +49 -0
  36. package/src/i18n/zh-CN.ts +184 -0
  37. package/src/icons.ts +71 -0
  38. package/src/index.ts +411 -0
  39. package/src/plugins/plantuml-encoder.ts +95 -0
  40. package/src/plugins/rehype-diagram.ts +218 -0
  41. package/src/plugins/rehype-ec-vt-rerun.ts +80 -0
  42. package/src/plugins/rehype-email.ts +75 -0
  43. package/src/plugins/rehype-github-card.ts +114 -0
  44. package/src/plugins/rehype.ts +284 -0
  45. package/src/plugins/remark-diagram.ts +78 -0
  46. package/src/plugins/remark-directives.ts +100 -0
  47. package/src/plugins/remark-excerpt.ts +29 -0
  48. package/src/plugins/remark-image-grid.ts +97 -0
  49. package/src/plugins/remark-reading-time.ts +38 -0
  50. package/src/plugins/scripts/diagram-panzoom.js +388 -0
  51. package/src/plugins/scripts/plantuml-theme-switch.js +90 -0
  52. package/src/routes/404.astro +14 -0
  53. package/src/routes/_hydrate.ts +34 -0
  54. package/src/routes/about.astro +25 -0
  55. package/src/routes/api/allPostMeta.json.ts +26 -0
  56. package/src/routes/archive.astro +81 -0
  57. package/src/routes/categories/[category].astro +37 -0
  58. package/src/routes/categories/index.astro +29 -0
  59. package/src/routes/friends.astro +83 -0
  60. package/src/routes/gallery/[album].astro +97 -0
  61. package/src/routes/gallery/index.astro +100 -0
  62. package/src/routes/guestbook.astro +37 -0
  63. package/src/routes/index.astro +47 -0
  64. package/src/routes/og/[...slug].ts +281 -0
  65. package/src/routes/page/[page].astro +53 -0
  66. package/src/routes/posts/[...slug].astro +350 -0
  67. package/src/routes/robots.txt.ts +18 -0
  68. package/src/routes/rss.xml.ts +37 -0
  69. package/src/routes/series/[name].astro +66 -0
  70. package/src/routes/series/index.astro +64 -0
  71. package/src/routes/sponsor.astro +84 -0
  72. package/src/routes/tags/[tag].astro +40 -0
  73. package/src/routes/tags/index.astro +29 -0
  74. package/src/schema.ts +1218 -0
  75. package/src/scripts/app.ts +1041 -0
  76. package/src/scripts/share-poster.ts +468 -0
  77. package/src/styles/global.css +4864 -0
  78. package/src/utils/crypto.ts +46 -0
  79. package/src/utils/gallery.ts +76 -0
  80. package/src/utils/lqip.ts +18 -0
  81. package/src/utils/related.ts +101 -0
  82. package/src/utils.ts +233 -0
  83. package/src/vite.ts +105 -0
@@ -0,0 +1,4864 @@
1
+ /* ==========================================================================
2
+ @windcoder/astro-theme-orchid — 全局样式
3
+ 移植自 design/prototype/styles.css(冻结原型),差异:
4
+ 1. accent 三变量化:--accent-h/s/l 由构建期 accentColor 注入,
5
+ 派生色用 calc 公式(与原型 #4a9d8f 硬编码值数学等价)
6
+ 2. 搜索浮层 / 调色面板 / 评论 / 画廊 modal 的 CSS 先行就位(M3b 启用对应 DOM)
7
+ 3. 补充:callout tip/important/danger、.h-anchor 标题锚点
8
+ (代码块样式自 §4.61 起由 Expressive Code 内联输出接管,本文件不再维护)
9
+ ========================================================================== */
10
+
11
+ @import "tailwindcss";
12
+
13
+ /* ---------- 1. 设计令牌 ---------- */
14
+ :root {
15
+ --accent-h: 170;
16
+ --accent-s: 36%;
17
+ --accent-l: 45%;
18
+ --accent: hsl(var(--accent-h) var(--accent-s) var(--accent-l));
19
+ --accent-deep: hsl(
20
+ var(--accent-h) var(--accent-s) calc(var(--accent-l) - 10%)
21
+ );
22
+ --accent-soft: hsl(var(--accent-h) calc(var(--accent-s) + 4%) 92%);
23
+ --accent-ink: hsl(
24
+ var(--accent-h) var(--accent-s) calc(var(--accent-l) - 15%)
25
+ );
26
+ --bg: #f6f4ef;
27
+ --bg-soft: #efede6;
28
+ --surface: #fdfcf9;
29
+ --ink: #2f2d2a;
30
+ --ink-2: #57544e;
31
+ --muted: #8b877e;
32
+ --border: #e3dfd4;
33
+ --border-2: #d5d0c2;
34
+ --font-display: "Noto Serif SC", "Songti SC", "STSong", "SimSun", serif;
35
+ --font-body:
36
+ -apple-system, "PingFang SC", "Segoe UI", "Microsoft YaHei", sans-serif;
37
+ --font-mono:
38
+ ui-monospace, "SF Mono", "JetBrains Mono", "Fira Code", monospace;
39
+ --radius: 12px;
40
+ --radius-sm: 8px;
41
+ --shadow-sm:
42
+ 0 1px 2px rgba(47, 45, 42, 0.05), 0 2px 8px rgba(47, 45, 42, 0.04);
43
+ --shadow-md:
44
+ 0 2px 6px rgba(47, 45, 42, 0.07), 0 10px 28px rgba(47, 45, 42, 0.08);
45
+ --header-h: 64px;
46
+ }
47
+
48
+ html.dark {
49
+ --accent: hsl(var(--accent-h) var(--accent-s) calc(var(--accent-l) + 10%));
50
+ --accent-deep: hsl(
51
+ var(--accent-h) var(--accent-s) calc(var(--accent-l) + 17%)
52
+ );
53
+ --accent-soft: hsl(var(--accent-h) calc(var(--accent-s) - 16%) 20%);
54
+ --accent-ink: hsl(
55
+ var(--accent-h) var(--accent-s) calc(var(--accent-l) + 25%)
56
+ );
57
+ --bg: #131516;
58
+ --bg-soft: #181b1c;
59
+ --surface: #1a1d1e;
60
+ --ink: #e5e2db;
61
+ --ink-2: #b9b5ac;
62
+ --muted: #8a867e;
63
+ --border: #282c2d;
64
+ --border-2: #333839;
65
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.25), 0 2px 8px rgba(0, 0, 0, 0.2);
66
+ --shadow-md: 0 2px 6px rgba(0, 0, 0, 0.3), 0 10px 28px rgba(0, 0, 0, 0.32);
67
+ }
68
+
69
+ /* ---------- 2. Reset ---------- */
70
+ *,
71
+ *::before,
72
+ *::after {
73
+ box-sizing: border-box;
74
+ }
75
+ * {
76
+ margin: 0;
77
+ }
78
+ html {
79
+ -webkit-text-size-adjust: 100%;
80
+ scroll-behavior: smooth;
81
+ /* 移动端横向滚动兜底(§4.13→§4.56):clip 不产生滚动容器、不影响 sticky;
82
+ 旧浏览器回退行(overflow-x: hidden 双写)移除以通过 biome noDuplicateProperties */
83
+ overflow-x: clip;
84
+ }
85
+ body {
86
+ font-family: var(--font-body);
87
+ font-size: 16px;
88
+ line-height: 1.75;
89
+ color: var(--ink);
90
+ background-color: var(--bg);
91
+ background-image:
92
+ radial-gradient(
93
+ 1100px 520px at 85% -10%,
94
+ hsl(var(--accent-h) 32% 90% / 0.55),
95
+ transparent 60%
96
+ ),
97
+ radial-gradient(
98
+ 900px 480px at -10% 20%,
99
+ hsl(var(--accent-h) 25% 88% / 0.4),
100
+ transparent 55%
101
+ );
102
+ background-attachment: fixed;
103
+ -webkit-font-smoothing: antialiased;
104
+ }
105
+ html.dark body {
106
+ background-image:
107
+ radial-gradient(
108
+ 1100px 520px at 85% -10%,
109
+ hsl(var(--accent-h) 25% 22% / 0.5),
110
+ transparent 60%
111
+ ),
112
+ radial-gradient(
113
+ 900px 480px at -10% 20%,
114
+ hsl(var(--accent-h) 20% 18% / 0.4),
115
+ transparent 55%
116
+ );
117
+ }
118
+ img {
119
+ display: block;
120
+ max-width: 100%;
121
+ }
122
+ [hidden] {
123
+ display: none !important;
124
+ }
125
+ button,
126
+ input {
127
+ font: inherit;
128
+ color: inherit;
129
+ }
130
+ button {
131
+ cursor: pointer;
132
+ background: none;
133
+ border: none;
134
+ padding: 0;
135
+ }
136
+ a {
137
+ color: var(--accent-ink);
138
+ text-decoration: none;
139
+ }
140
+ a:hover {
141
+ color: var(--accent-deep);
142
+ }
143
+ html.dark a:hover {
144
+ color: var(--accent);
145
+ }
146
+ ::selection {
147
+ background: var(--accent-soft);
148
+ color: var(--accent-ink);
149
+ }
150
+
151
+ .shell {
152
+ max-width: var(--page-width, 1600px);
153
+ margin-inline: auto;
154
+ /* §4.46 对齐参考站 px-2 md:px-4:容器内边距 16px,页面留白交给列距与卡片内边距 */
155
+ padding-inline: 16px;
156
+ }
157
+ /* xl(1280+) 对齐参考站 w-92vw 策略:容器取 min(92vw, pageWidth),
158
+ 宽屏最多 1600px 居中、两侧留 4% 呼吸位;<1280px 全宽铺满(§4.32 迭代) */
159
+ @media (min-width: 1280px) {
160
+ .shell {
161
+ max-width: min(92vw, var(--page-width, 1600px));
162
+ }
163
+ }
164
+ .muted {
165
+ color: var(--muted);
166
+ }
167
+
168
+ .skip-link {
169
+ position: absolute;
170
+ left: 16px;
171
+ top: -48px;
172
+ z-index: 200;
173
+ padding: 8px 16px;
174
+ border-radius: var(--radius-sm);
175
+ background: var(--accent);
176
+ color: #fff;
177
+ transition: top 0.2s;
178
+ }
179
+ .skip-link:focus {
180
+ top: 12px;
181
+ }
182
+
183
+ /* ---------- 3. Header ---------- */
184
+ .site-header {
185
+ position: sticky;
186
+ top: 0;
187
+ z-index: 100;
188
+ height: var(--header-h);
189
+ background: color-mix(in srgb, var(--bg) 78%, transparent);
190
+ -webkit-backdrop-filter: blur(14px);
191
+ backdrop-filter: blur(14px);
192
+ border-bottom: 1px solid var(--border);
193
+ }
194
+ .header-inner {
195
+ display: flex;
196
+ align-items: center;
197
+ gap: 24px;
198
+ height: var(--header-h);
199
+ }
200
+ .site-title {
201
+ font-family: var(--font-display);
202
+ font-size: 22px;
203
+ font-weight: 700;
204
+ letter-spacing: 0.06em;
205
+ color: var(--ink);
206
+ white-space: nowrap;
207
+ /* Logo(§4.20):随标题行内对齐,flex 居中保证不同高度图片垂直居中 */
208
+ display: inline-flex;
209
+ align-items: center;
210
+ gap: 8px;
211
+ }
212
+ .nav-logo {
213
+ width: auto;
214
+ height: 26px;
215
+ border-radius: 5px;
216
+ flex: none;
217
+ }
218
+ .site-title:hover {
219
+ color: var(--accent-deep);
220
+ }
221
+ html.dark .site-title:hover {
222
+ color: var(--accent);
223
+ }
224
+ .site-nav {
225
+ display: flex;
226
+ align-items: center;
227
+ gap: 4px;
228
+ margin-left: 8px;
229
+ }
230
+ .nav-link {
231
+ padding: 6px 14px;
232
+ border-radius: 999px;
233
+ color: var(--ink-2);
234
+ font-size: 15px;
235
+ transition:
236
+ color 0.15s,
237
+ background-color 0.15s;
238
+ }
239
+ .nav-link:hover {
240
+ color: var(--ink);
241
+ background: var(--bg-soft);
242
+ }
243
+ /* nav 子菜单(§4.16):桌面 hover 展开,无 href 父项/移动端点击 toggle */
244
+ .nav-item {
245
+ position: relative;
246
+ }
247
+ .nav-sub-toggle {
248
+ background: none;
249
+ border: 0;
250
+ cursor: pointer;
251
+ font: inherit;
252
+ }
253
+ /* 父项 chevron(§4.27):label 后下拉标识,桌面 hover / 移动端展开时旋转 */
254
+ .has-sub > .nav-link {
255
+ display: inline-flex;
256
+ align-items: center;
257
+ }
258
+ .nav-caret {
259
+ flex: none;
260
+ width: 14px;
261
+ height: 14px;
262
+ margin-inline-start: 4px;
263
+ transition: transform 0.15s;
264
+ }
265
+ .nav-item.has-sub:hover .nav-caret,
266
+ .nav-item.open-sub .nav-caret {
267
+ transform: rotate(180deg);
268
+ }
269
+ .nav-sub {
270
+ position: absolute;
271
+ top: calc(100% + 6px);
272
+ left: 50%;
273
+ transform: translateX(-50%) translateY(4px);
274
+ min-width: 128px;
275
+ padding: 6px;
276
+ border-radius: var(--radius);
277
+ background: var(--surface);
278
+ border: 1px solid var(--border);
279
+ box-shadow: var(--shadow-md);
280
+ display: flex;
281
+ flex-direction: column;
282
+ gap: 2px;
283
+ opacity: 0;
284
+ visibility: hidden;
285
+ pointer-events: none;
286
+ transition:
287
+ opacity 0.15s,
288
+ transform 0.15s,
289
+ visibility 0.15s;
290
+ z-index: 110;
291
+ }
292
+ /* 透明桥(§4.40):补齐面板与父项间 6px 空隙,鼠标移向子菜单不丢 :hover;
293
+ 仅面板展开态(hover/open-sub 下 pointer-events 生效)需要承接 */
294
+ .nav-sub::before {
295
+ content: "";
296
+ position: absolute;
297
+ top: -7px;
298
+ left: 0;
299
+ right: 0;
300
+ height: 7px;
301
+ }
302
+ .nav-item.has-sub:hover .nav-sub,
303
+ .nav-item.open-sub .nav-sub {
304
+ opacity: 1;
305
+ visibility: visible;
306
+ pointer-events: auto;
307
+ transform: translateX(-50%) translateY(0);
308
+ }
309
+ .nav-sub-link {
310
+ padding: 7px 12px;
311
+ border-radius: var(--radius-sm);
312
+ font-size: 14px;
313
+ color: var(--ink-2);
314
+ white-space: nowrap;
315
+ }
316
+ .nav-sub-link:hover {
317
+ color: var(--ink);
318
+ background: var(--bg-soft);
319
+ }
320
+ .nav-item.is-active > .nav-link,
321
+ .nav-item.is-active > .nav-sub-toggle {
322
+ color: var(--accent-ink);
323
+ background: var(--accent-soft);
324
+ }
325
+ @media (max-width: 860px) {
326
+ .nav-sub-toggle {
327
+ width: 100%;
328
+ text-align: left;
329
+ justify-content: flex-start;
330
+ }
331
+ /* static 布局下伪元素会相对 nav-item 错位,移动端禁用桥 */
332
+ .nav-sub::before {
333
+ content: none;
334
+ }
335
+ .nav-sub {
336
+ position: static;
337
+ transform: none;
338
+ display: none;
339
+ border: 0;
340
+ background: transparent;
341
+ box-shadow: none;
342
+ padding: 2px 0 4px 14px;
343
+ min-width: 0;
344
+ opacity: 1;
345
+ visibility: visible;
346
+ pointer-events: auto;
347
+ }
348
+ .nav-item.has-sub:hover .nav-sub {
349
+ opacity: 1;
350
+ visibility: visible;
351
+ pointer-events: auto;
352
+ transform: none;
353
+ }
354
+ .nav-item.open-sub .nav-sub {
355
+ display: flex;
356
+ transform: none;
357
+ }
358
+ }
359
+ .nav-link.is-active {
360
+ color: var(--accent-ink);
361
+ background: var(--accent-soft);
362
+ font-weight: 500;
363
+ }
364
+ .header-actions {
365
+ margin-left: auto;
366
+ display: flex;
367
+ align-items: center;
368
+ gap: 6px;
369
+ }
370
+ .icon-btn {
371
+ display: inline-flex;
372
+ align-items: center;
373
+ justify-content: center;
374
+ width: 38px;
375
+ height: 38px;
376
+ border-radius: 10px;
377
+ color: var(--ink-2);
378
+ transition:
379
+ color 0.15s,
380
+ background-color 0.15s;
381
+ }
382
+ .icon-btn:hover {
383
+ color: var(--ink);
384
+ background: var(--bg-soft);
385
+ }
386
+ .icon-btn svg {
387
+ width: 20px;
388
+ height: 20px;
389
+ }
390
+ #modeToggle .i-sun {
391
+ display: none;
392
+ }
393
+ html.dark #modeToggle .i-moon {
394
+ display: none;
395
+ }
396
+ html.dark #modeToggle .i-sun {
397
+ display: block;
398
+ }
399
+ .nav-burger {
400
+ display: none;
401
+ }
402
+
403
+ /* palette(调色面板,M3b 启用入口按钮) */
404
+ .palette-wrap {
405
+ position: relative;
406
+ }
407
+ .palette-pop {
408
+ position: absolute;
409
+ right: 0;
410
+ top: calc(100% + 10px);
411
+ z-index: 110;
412
+ min-width: 216px;
413
+ padding: 14px;
414
+ background: var(--surface);
415
+ border: 1px solid var(--border);
416
+ border-radius: var(--radius);
417
+ box-shadow: var(--shadow-md);
418
+ }
419
+ .palette-title {
420
+ font-size: 12px;
421
+ color: var(--muted);
422
+ margin-bottom: 10px;
423
+ letter-spacing: 0.08em;
424
+ }
425
+ .palette-row {
426
+ display: flex;
427
+ flex-wrap: wrap;
428
+ gap: 10px;
429
+ }
430
+ .swatch {
431
+ width: 28px;
432
+ height: 28px;
433
+ border-radius: 50%;
434
+ background: var(--sw);
435
+ border: 2px solid transparent;
436
+ box-shadow: inset 0 0 0 2px var(--surface);
437
+ transition:
438
+ transform 0.15s,
439
+ border-color 0.15s;
440
+ }
441
+ .swatch:hover {
442
+ transform: scale(1.12);
443
+ }
444
+ .swatch.is-active {
445
+ border-color: var(--accent-ink);
446
+ }
447
+ .hue-slider {
448
+ width: 100%;
449
+ height: 14px;
450
+ margin-top: 14px;
451
+ appearance: none;
452
+ -webkit-appearance: none;
453
+ background: linear-gradient(
454
+ to right,
455
+ hsl(0 80% 60%),
456
+ hsl(30 80% 60%),
457
+ hsl(60 80% 60%),
458
+ hsl(100 80% 60%),
459
+ hsl(140 80% 60%),
460
+ hsl(170 80% 60%),
461
+ hsl(210 80% 60%),
462
+ hsl(250 80% 60%),
463
+ hsl(290 80% 60%),
464
+ hsl(330 80% 60%),
465
+ hsl(360 80% 60%)
466
+ );
467
+ border-radius: 999px;
468
+ cursor: pointer;
469
+ outline-offset: 3px;
470
+ }
471
+ .hue-slider::-webkit-slider-thumb {
472
+ appearance: none;
473
+ -webkit-appearance: none;
474
+ width: 20px;
475
+ height: 20px;
476
+ border-radius: 50%;
477
+ background: var(--surface);
478
+ border: 2px solid var(--accent);
479
+ box-shadow: var(--shadow-sm);
480
+ }
481
+ .hue-slider::-moz-range-thumb {
482
+ width: 20px;
483
+ height: 20px;
484
+ border-radius: 50%;
485
+ background: var(--surface);
486
+ border: 2px solid var(--accent);
487
+ box-shadow: var(--shadow-sm);
488
+ }
489
+ .palette-foot {
490
+ display: flex;
491
+ align-items: center;
492
+ justify-content: space-between;
493
+ margin-top: 12px;
494
+ }
495
+ .hue-badge {
496
+ font-size: 12px;
497
+ color: var(--muted);
498
+ font-variant-numeric: tabular-nums;
499
+ }
500
+ .palette-reset {
501
+ font-size: 12px;
502
+ color: var(--ink-2);
503
+ padding: 3px 10px;
504
+ border-radius: 8px;
505
+ border: 1px solid var(--border);
506
+ transition:
507
+ color 0.15s,
508
+ border-color 0.15s,
509
+ background-color 0.15s;
510
+ }
511
+ .palette-reset:hover {
512
+ color: var(--accent-ink);
513
+ border-color: var(--accent);
514
+ background: var(--accent-soft);
515
+ }
516
+
517
+ /* 搜索(M3b-b6→§4.56):导航栏内联搜索框 + 结果浮层(对齐参考项目 Navbar 形态) */
518
+ .search-wrap {
519
+ position: relative;
520
+ }
521
+ /* 桌面内联搜索框:icon + input,输入即搜,focus 扩宽 */
522
+ .nav-search {
523
+ display: flex;
524
+ align-items: center;
525
+ gap: 6px;
526
+ height: 38px;
527
+ padding: 0 12px;
528
+ border-radius: 10px;
529
+ background: var(--bg-soft);
530
+ color: var(--muted);
531
+ transition:
532
+ background-color 0.15s,
533
+ color 0.15s;
534
+ }
535
+ .nav-search:hover,
536
+ .nav-search:focus-within {
537
+ color: var(--ink-2);
538
+ }
539
+ .nav-search svg {
540
+ width: 16px;
541
+ height: 16px;
542
+ flex: none;
543
+ }
544
+ .nav-search input {
545
+ width: 150px;
546
+ border: none;
547
+ outline: none;
548
+ background: transparent;
549
+ font: inherit;
550
+ font-size: 14px;
551
+ color: var(--ink);
552
+ transition: width 0.2s;
553
+ }
554
+ .nav-search input:focus {
555
+ width: 220px;
556
+ }
557
+ .nav-search input::placeholder {
558
+ color: var(--muted);
559
+ }
560
+ .nav-search input::-webkit-search-cancel-button {
561
+ -webkit-appearance: none;
562
+ }
563
+ /* 移动端 icon 按钮:<640px 替代内联框(对齐参考项目移动端形态) */
564
+ .nav-search-toggle {
565
+ display: none;
566
+ }
567
+ .search-pop {
568
+ position: absolute;
569
+ right: 0;
570
+ top: calc(100% + 10px);
571
+ z-index: 110;
572
+ width: 380px;
573
+ max-width: calc(100vw - 32px);
574
+ background: var(--surface);
575
+ border: 1px solid var(--border);
576
+ border-radius: var(--radius);
577
+ box-shadow: var(--shadow-md);
578
+ overflow: hidden;
579
+ }
580
+ /* 浮层内输入框仅移动端显示(桌面输入在内联框中完成) */
581
+ .search-bar {
582
+ display: none;
583
+ align-items: center;
584
+ gap: 8px;
585
+ padding: 10px 14px;
586
+ border-bottom: 1px solid var(--border);
587
+ color: var(--muted);
588
+ }
589
+ .search-bar svg {
590
+ width: 16px;
591
+ height: 16px;
592
+ flex: none;
593
+ }
594
+ .search-bar input {
595
+ flex: 1;
596
+ min-width: 0;
597
+ border: none;
598
+ outline: none;
599
+ background: transparent;
600
+ font: inherit;
601
+ font-size: 14px;
602
+ color: var(--ink);
603
+ }
604
+ .search-bar input::placeholder {
605
+ color: var(--muted);
606
+ }
607
+ .search-bar input::-webkit-search-cancel-button {
608
+ -webkit-appearance: none;
609
+ }
610
+ .search-results {
611
+ max-height: 56vh;
612
+ overflow-y: auto;
613
+ overscroll-behavior: contain;
614
+ }
615
+ .search-item {
616
+ display: block;
617
+ padding: 10px 14px;
618
+ transition: background-color 0.15s;
619
+ }
620
+ .search-item:hover {
621
+ background: var(--bg-soft);
622
+ }
623
+ .search-item + .search-item {
624
+ border-top: 1px solid var(--border);
625
+ }
626
+ .search-item-title {
627
+ font-size: 14px;
628
+ font-weight: 500;
629
+ color: var(--ink);
630
+ }
631
+ .search-item-excerpt {
632
+ margin-top: 3px;
633
+ font-size: 12px;
634
+ line-height: 1.6;
635
+ color: var(--muted);
636
+ display: -webkit-box;
637
+ -webkit-line-clamp: 2;
638
+ -webkit-box-orient: vertical;
639
+ overflow: hidden;
640
+ }
641
+ .search-item-excerpt mark,
642
+ .search-item-title mark {
643
+ background: var(--accent-soft);
644
+ color: var(--accent-ink);
645
+ padding: 0 1px;
646
+ border-radius: 3px;
647
+ }
648
+ .search-hint {
649
+ padding: 14px;
650
+ font-size: 13px;
651
+ color: var(--muted);
652
+ text-align: center;
653
+ }
654
+
655
+ /* ---------- 3.5 背景壁纸(§4.35,banner 单模式) ---------- */
656
+ /* Header 为 sticky 且背景半透明 + 毛玻璃:负 margin 让横幅上缘滑入 Header 底下 */
657
+ .wallpaper-banner {
658
+ position: relative;
659
+ height: var(--banner-h, 32vh);
660
+ margin-top: calc(-1 * var(--header-h));
661
+ overflow: hidden;
662
+ }
663
+ .wallpaper-banner img {
664
+ display: block;
665
+ width: 100%;
666
+ height: 100%;
667
+ object-fit: cover;
668
+ object-position: var(--banner-pos, center);
669
+ }
670
+ /* 黑蒙层:深浅模式同色(orchid-blog 口径),只保证压暗不改变色调 */
671
+ .wallpaper-dim {
672
+ position: absolute;
673
+ inset: 0;
674
+ background: rgba(0, 0, 0, var(--banner-dim, 0.2));
675
+ }
676
+ /* hero 叠加(§4.39):首页 hero 启用时主句/副句居中压到 banner 上;
677
+ banner 上缘滑入 Header 底下(负 margin),文字区加 padding-top 补偿做视觉居中 */
678
+ .wallpaper-hero {
679
+ position: absolute;
680
+ inset: 0;
681
+ z-index: 1;
682
+ display: flex;
683
+ flex-direction: column;
684
+ align-items: center;
685
+ justify-content: center;
686
+ padding: var(--header-h) 24px 0;
687
+ text-align: center;
688
+ }
689
+ .wallpaper-hero .hero-quote {
690
+ color: #fff;
691
+ text-shadow: 0 2px 16px rgba(0, 0, 0, 0.45);
692
+ }
693
+ /* banner 上强调色需提亮:accent-ink 在黑蒙层上偏暗,混入白色保证可读 */
694
+ .wallpaper-hero .hero-quote em {
695
+ color: color-mix(in srgb, var(--accent) 45%, #fff);
696
+ }
697
+ .wallpaper-hero .hero-sub {
698
+ color: rgba(255, 255, 255, 0.88);
699
+ text-shadow: 0 1px 10px rgba(0, 0, 0, 0.4);
700
+ }
701
+
702
+ /* ---------- 4. Main 通用 ---------- */
703
+ .site-main {
704
+ min-height: calc(100vh - var(--header-h) - 200px);
705
+ padding: 40px 0 64px;
706
+ }
707
+ .section-title {
708
+ font-family: var(--font-display);
709
+ font-size: 22px;
710
+ font-weight: 700;
711
+ margin-bottom: 20px;
712
+ letter-spacing: 0.02em;
713
+ }
714
+ .card {
715
+ background: var(--surface);
716
+ border: 1px solid var(--border);
717
+ border-radius: var(--radius);
718
+ box-shadow: var(--shadow-sm);
719
+ }
720
+ .chip {
721
+ display: inline-flex;
722
+ align-items: center;
723
+ padding: 2px 12px;
724
+ border-radius: 999px;
725
+ font-size: 13px;
726
+ /* §4.46 对齐参考站 text-sm font-bold 标签层级 */
727
+ font-weight: 600;
728
+ color: var(--ink-2);
729
+ background: var(--bg-soft);
730
+ border: 1px solid var(--border);
731
+ transition:
732
+ color 0.15s,
733
+ border-color 0.15s,
734
+ background-color 0.15s;
735
+ }
736
+ .chip:hover {
737
+ color: var(--accent-ink);
738
+ border-color: var(--accent);
739
+ }
740
+ .chip.is-on {
741
+ color: var(--accent-ink);
742
+ background: var(--accent-soft);
743
+ border-color: var(--accent);
744
+ }
745
+ .btn {
746
+ display: inline-flex;
747
+ align-items: center;
748
+ gap: 6px;
749
+ padding: 9px 22px;
750
+ border-radius: 999px;
751
+ background: var(--accent);
752
+ color: #fff;
753
+ font-size: 15px;
754
+ border: 1px solid var(--accent);
755
+ transition:
756
+ background-color 0.15s,
757
+ border-color 0.15s,
758
+ transform 0.15s;
759
+ }
760
+ .btn:hover {
761
+ background: var(--accent-deep);
762
+ border-color: var(--accent-deep);
763
+ color: #fff;
764
+ }
765
+ html.dark .btn:hover {
766
+ background: var(--accent);
767
+ border-color: var(--accent);
768
+ color: #131516;
769
+ }
770
+ .btn-ghost {
771
+ background: transparent;
772
+ color: var(--accent-ink);
773
+ border-color: var(--border-2);
774
+ }
775
+ .btn-ghost:hover {
776
+ background: var(--accent-soft);
777
+ color: var(--accent-ink);
778
+ border-color: var(--accent);
779
+ }
780
+
781
+ /* reveal */
782
+ .reveal {
783
+ opacity: 0;
784
+ transform: translateY(14px);
785
+ transition:
786
+ opacity 0.6s ease,
787
+ transform 0.6s ease;
788
+ }
789
+ .reveal.is-in {
790
+ opacity: 1;
791
+ transform: none;
792
+ }
793
+
794
+ /* ---------- 5. 首页 ---------- */
795
+ .hero {
796
+ padding: 28px 0 36px;
797
+ text-align: center;
798
+ }
799
+ .hero-quote {
800
+ font-family: var(--font-display);
801
+ font-size: clamp(26px, 4vw, 38px);
802
+ font-weight: 700;
803
+ letter-spacing: 0.04em;
804
+ }
805
+ .hero-quote em {
806
+ font-style: normal;
807
+ color: var(--accent-ink);
808
+ }
809
+ .hero-sub {
810
+ margin-top: 14px;
811
+ color: var(--muted);
812
+ font-size: 15px;
813
+ }
814
+
815
+ .home-layout {
816
+ display: grid;
817
+ /* minmax(0,1fr)(§4.24):单列下限归零,防分类栏/文章卡等宽内容撑破轨道产生横向滚动 */
818
+ grid-template-columns: minmax(0, 1fr);
819
+ gap: 32px;
820
+ align-items: start;
821
+ }
822
+ @media (min-width: 1025px) {
823
+ .home-layout {
824
+ grid-template-columns: minmax(0, 1fr) 280px;
825
+ /* §4.46 对齐参考站 gap-4:桌面列距 16px(移动端保持 32px 纵向节奏) */
826
+ gap: 16px;
827
+ }
828
+ }
829
+
830
+ .post-card {
831
+ display: grid;
832
+ grid-template-columns: 1fr;
833
+ position: relative;
834
+ overflow: hidden;
835
+ background: var(--surface);
836
+ border: 1px solid var(--border);
837
+ border-radius: var(--radius);
838
+ box-shadow: var(--shadow-sm);
839
+ transition:
840
+ box-shadow 0.2s,
841
+ transform 0.2s,
842
+ border-color 0.2s;
843
+ }
844
+ .post-card:hover {
845
+ box-shadow: var(--shadow-md);
846
+ transform: translateY(-2px);
847
+ border-color: var(--border-2);
848
+ }
849
+ .post-cover {
850
+ position: relative;
851
+ aspect-ratio: 16 / 9;
852
+ overflow: hidden;
853
+ }
854
+ .post-cover img {
855
+ width: 100%;
856
+ height: 100%;
857
+ object-fit: cover;
858
+ transition: transform 0.5s ease;
859
+ }
860
+ .post-card:hover .post-cover img {
861
+ transform: scale(1.03);
862
+ }
863
+ .post-body {
864
+ padding: 22px 24px 24px;
865
+ }
866
+ /* 无封面卡:为右侧 .post-enter 竖条(52px + 右偏 12px + 间隙)预留 80px(§4.34 迭代,
867
+ 对齐参考站 no-cover content calc(100%-52px-12px) 留白;compact/text-only 行不预留) */
868
+ .post-card.no-cover:not(.compact) .post-body {
869
+ padding-right: 80px;
870
+ }
871
+ .post-title {
872
+ font-family: var(--font-display);
873
+ font-size: 20px;
874
+ font-weight: 700;
875
+ line-height: 1.5;
876
+ }
877
+ .post-title a {
878
+ color: var(--ink);
879
+ }
880
+ .post-title a:hover {
881
+ color: var(--accent-deep);
882
+ }
883
+ html.dark .post-title a:hover {
884
+ color: var(--accent);
885
+ }
886
+ .post-card:hover .post-title a {
887
+ color: var(--accent-deep);
888
+ }
889
+ html.dark .post-card:hover .post-title a {
890
+ color: var(--accent);
891
+ }
892
+ .post-excerpt {
893
+ margin-top: 8px;
894
+ color: var(--ink-2);
895
+ font-size: 15px;
896
+ display: -webkit-box;
897
+ -webkit-line-clamp: 2;
898
+ -webkit-box-orient: vertical;
899
+ overflow: hidden;
900
+ }
901
+ .post-meta {
902
+ margin-top: 12px;
903
+ display: flex;
904
+ flex-wrap: wrap;
905
+ gap: 8px 14px;
906
+ color: var(--muted);
907
+ font-size: 13px;
908
+ }
909
+ .post-meta .dot::before {
910
+ content: "·";
911
+ margin-right: 14px;
912
+ }
913
+ .post-tags {
914
+ margin-top: 12px;
915
+ display: flex;
916
+ flex-wrap: wrap;
917
+ gap: 8px;
918
+ }
919
+ .pin-badge {
920
+ position: absolute;
921
+ top: 14px;
922
+ left: 14px;
923
+ z-index: 2;
924
+ padding: 3px 12px;
925
+ border-radius: 999px;
926
+ background: var(--accent);
927
+ color: #fff;
928
+ font-size: 12px;
929
+ letter-spacing: 0.1em;
930
+ }
931
+ /* 无封面卡右侧进入按钮竖条(对齐参考站 post-card-enter-btn):
932
+ 上/下/右各内缩 12px、宽 52px,浅 accent 底 + chevron */
933
+ .post-enter {
934
+ position: absolute;
935
+ top: 12px;
936
+ right: 12px;
937
+ bottom: 12px;
938
+ z-index: 2;
939
+ width: 52px;
940
+ display: flex;
941
+ align-items: center;
942
+ justify-content: center;
943
+ border-radius: 12px;
944
+ background: var(--accent-soft);
945
+ color: var(--accent-deep);
946
+ transition:
947
+ background 0.2s,
948
+ transform 0.15s;
949
+ }
950
+ .post-enter:hover {
951
+ background: color-mix(in srgb, var(--accent) 22%, var(--surface));
952
+ }
953
+ .post-enter:active {
954
+ transform: scale(0.95);
955
+ }
956
+ .post-enter svg {
957
+ width: 26px;
958
+ height: 26px;
959
+ }
960
+ html.dark .post-enter {
961
+ color: var(--accent);
962
+ }
963
+ /* compact 紧凑行不挂竖条(其封面/文本行本身已横排) */
964
+ .post-card.compact .post-enter {
965
+ display: none;
966
+ }
967
+ /* 置顶卡(featured,§4.55):列表形态下与普通卡同构同高——封面左置内缩圆角块,
968
+ 样式镜像普通卡右置封面(同 30% 宽 + 16px 边距 + 12px 圆角,图文间隔一致),
969
+ 不再使用贴边大图 + 加大标题的特化形态 */
970
+ @media (min-width: 641px) {
971
+ .post-list:not(.grid-mode) .post-card.featured.has-cover .post-cover {
972
+ position: absolute;
973
+ top: 16px;
974
+ left: 16px;
975
+ bottom: 16px;
976
+ right: auto;
977
+ width: 30%;
978
+ aspect-ratio: auto;
979
+ min-height: 0;
980
+ border-radius: 12px;
981
+ }
982
+ .post-list:not(.grid-mode) .post-card.featured.has-cover .post-body {
983
+ display: flex;
984
+ flex-direction: column;
985
+ justify-content: center;
986
+ min-height: 196px;
987
+ /* 左留:封面 30% + 左偏 16px + 图文间隙 16px;右留 32px 常规边距(§4.56 镜像普通卡) */
988
+ padding: 28px 32px 28px calc(30% + 32px);
989
+ }
990
+ }
991
+ .post-card.text-only .post-cover {
992
+ display: none;
993
+ }
994
+ /* 列表第三种形态:紧凑行(compact),可按篇混排 */
995
+ .post-card.compact {
996
+ grid-template-columns: 128px 1fr;
997
+ }
998
+ .post-card.compact .post-cover {
999
+ aspect-ratio: 4 / 3;
1000
+ }
1001
+ .post-card.compact .post-body {
1002
+ padding: 13px 18px;
1003
+ align-self: center;
1004
+ }
1005
+ .post-card.compact .post-title {
1006
+ font-size: 16px;
1007
+ line-height: 1.55;
1008
+ }
1009
+ .post-card.compact .post-excerpt {
1010
+ -webkit-line-clamp: 1;
1011
+ margin-top: 4px;
1012
+ font-size: 13.5px;
1013
+ }
1014
+ .post-card.compact .post-meta {
1015
+ margin-top: 6px;
1016
+ font-size: 12.5px;
1017
+ }
1018
+ .post-card.compact .post-tags {
1019
+ display: none;
1020
+ }
1021
+ .post-card.compact.text-only {
1022
+ grid-template-columns: 1fr;
1023
+ }
1024
+
1025
+ /* 列表形态切换(§4.34→§4.55):按钮移至导航栏 actions 区(复用 .icon-btn 形态),
1026
+ 仅首页/列表页显示(body[data-page="home"] 显隐,无闪烁);图标由按钮 aria-pressed 驱动 */
1027
+ .layout-switch {
1028
+ display: none;
1029
+ }
1030
+ body[data-page="home"] .layout-switch {
1031
+ display: inline-flex;
1032
+ }
1033
+ .layout-switch .ic-grid {
1034
+ display: none;
1035
+ }
1036
+ .layout-switch[aria-pressed="true"] .ic-list {
1037
+ display: none;
1038
+ }
1039
+ .layout-switch[aria-pressed="true"] .ic-grid {
1040
+ display: block;
1041
+ }
1042
+ .post-list.grid-mode {
1043
+ display: grid;
1044
+ grid-template-columns: repeat(auto-fill, minmax(var(--col-w, 320px), 1fr));
1045
+ gap: 20px;
1046
+ align-items: stretch;
1047
+ }
1048
+ /* 非卡片条目(分类栏/标题/分页/空态)占满整行;
1049
+ :has(.post-card) 例外——兼容站点 override 把卡片包在 div.relative 里(demo 即如此),
1050
+ 包裹层应作为普通网格单元参与排列,否则会整行跨越把网格压成单列 */
1051
+ .post-list.grid-mode > :not(.post-card):not(:has(.post-card)) {
1052
+ grid-column: 1 / -1;
1053
+ }
1054
+ /* 卡片包裹层(override 场景):自身拉伸为弹性盒,让内部卡片填满单元并等高 */
1055
+ .post-list.grid-mode > :has(.post-card) {
1056
+ display: flex;
1057
+ min-width: 0;
1058
+ }
1059
+ .post-list.grid-mode > :has(.post-card) > .post-card {
1060
+ flex: 1;
1061
+ min-width: 0;
1062
+ }
1063
+ /* featured(无论直接 article 还是 override 包裹层)始终独占整行 */
1064
+ .post-list.grid-mode > :has(.post-card.featured) {
1065
+ grid-column: 1 / -1;
1066
+ }
1067
+ /* 列表形态:flex 纵向 gap 统一间距(对齐参考站 flex-col gap-4),
1068
+ 不依赖相邻 margin,杜绝 margin 折叠/与 gap 叠加;子项自带垂直 margin 归零 */
1069
+ .post-list:not(.grid-mode) {
1070
+ display: flex;
1071
+ flex-direction: column;
1072
+ gap: 20px;
1073
+ }
1074
+ /* 两种形态统一由容器 gap 控制节奏,子项自带垂直 margin 归零(grid/flex 下 margin 不折叠会叠加) */
1075
+ .post-list > * {
1076
+ margin-block: 0;
1077
+ }
1078
+ /* 网格内全部卡片恢复纵向、封面在上(覆盖 featured 横排与 compact 紧凑行) */
1079
+ .post-list.grid-mode .post-card {
1080
+ display: flex;
1081
+ flex-direction: column;
1082
+ grid-template-columns: none;
1083
+ }
1084
+ .post-list.grid-mode .post-card.featured {
1085
+ grid-column: 1 / -1;
1086
+ }
1087
+ .post-list.grid-mode .post-card.featured .post-cover {
1088
+ aspect-ratio: 16 / 9;
1089
+ min-height: 0;
1090
+ }
1091
+ .post-list.grid-mode .post-card.compact .post-cover {
1092
+ aspect-ratio: 16 / 9;
1093
+ }
1094
+ .post-list.grid-mode .post-card.compact .post-body {
1095
+ padding: 18px 20px 20px;
1096
+ align-self: auto;
1097
+ }
1098
+ /* 随机封面全源失败(§4.33):藏 img 露出 LQIP 渐变占位 */
1099
+ .post-card .post-cover img.cover-broken {
1100
+ visibility: hidden;
1101
+ }
1102
+ /* 移动端小屏(§4.55):布局开关对移动端不生效——网格强制还原单列上下布局
1103
+ (卡片本就 flex column:封面在上、标题/简介等文字在下) */
1104
+ @media (max-width: 767px) {
1105
+ .post-list.grid-mode {
1106
+ display: flex;
1107
+ flex-direction: column;
1108
+ gap: 20px;
1109
+ }
1110
+ }
1111
+ /* 列表形态(非网格)普通 cover 卡桌面:封面右浮为内缩圆角块,正文居左铺满,
1112
+ 与网格形态(封面在上全宽贴边)拉开结构差异。对齐参考站 post-card-image:
1113
+ absolute top/right/bottom 16px + 宽 30% + 独立圆角,封面不贴卡片边;
1114
+ 无封面卡(.no-cover)不命中本规则,文字不会被挤到左列 */
1115
+ @media (min-width: 641px) {
1116
+ .post-list:not(.grid-mode)
1117
+ .post-card:not(.featured):not(.compact).has-cover
1118
+ .post-cover {
1119
+ position: absolute;
1120
+ top: 16px;
1121
+ right: 16px;
1122
+ bottom: 16px;
1123
+ left: auto;
1124
+ width: 30%;
1125
+ aspect-ratio: auto;
1126
+ min-height: 0;
1127
+ border-radius: 12px;
1128
+ }
1129
+ .post-list:not(.grid-mode)
1130
+ .post-card:not(.featured):not(.compact).has-cover
1131
+ .post-body {
1132
+ display: flex;
1133
+ flex-direction: column;
1134
+ justify-content: center;
1135
+ min-height: 196px;
1136
+ /* 右留:封面 30% + 右偏 16px + 图文间隙 16px */
1137
+ padding: 28px calc(30% + 32px) 28px 32px;
1138
+ }
1139
+ }
1140
+
1141
+ /* 分类导航栏(§4.15):全站顶部横条,pill 横排 + 滚动区隐藏滚动条 */
1142
+ .category-bar {
1143
+ display: flex;
1144
+ align-items: center;
1145
+ gap: 6px;
1146
+ margin-bottom: 24px;
1147
+ padding: 8px 12px;
1148
+ }
1149
+ .bar-scroll {
1150
+ display: flex;
1151
+ align-items: center;
1152
+ gap: 6px;
1153
+ flex: 1;
1154
+ min-width: 0;
1155
+ overflow-x: auto;
1156
+ scrollbar-width: none;
1157
+ }
1158
+ .bar-scroll::-webkit-scrollbar {
1159
+ display: none;
1160
+ }
1161
+ .category-pill {
1162
+ display: inline-flex;
1163
+ align-items: center;
1164
+ gap: 6px;
1165
+ padding: 6px 14px;
1166
+ border-radius: 999px;
1167
+ font-size: 14px;
1168
+ color: var(--ink-2);
1169
+ white-space: nowrap;
1170
+ transition:
1171
+ color 0.15s,
1172
+ background-color 0.15s;
1173
+ }
1174
+ .category-pill:hover {
1175
+ color: var(--ink);
1176
+ background: var(--bg-soft);
1177
+ }
1178
+ .category-pill.is-active {
1179
+ color: var(--accent-ink);
1180
+ background: var(--accent-soft);
1181
+ }
1182
+ .pill-count {
1183
+ padding: 3px 7px;
1184
+ border-radius: 999px;
1185
+ background: var(--bg-soft);
1186
+ color: var(--muted);
1187
+ font-size: 11px;
1188
+ line-height: 1;
1189
+ font-variant-numeric: tabular-nums;
1190
+ }
1191
+ .category-pill.is-active .pill-count {
1192
+ background: var(--accent);
1193
+ color: #fff;
1194
+ }
1195
+ .bar-divider {
1196
+ width: 1px;
1197
+ height: 18px;
1198
+ flex: none;
1199
+ margin-inline: 4px;
1200
+ background: var(--border);
1201
+ }
1202
+
1203
+ /* 溢出横向滚动 + 右缘渐隐(§4.21,替代 §4.18 折叠下拉):
1204
+ app.ts 检测 scrollWidth 溢出后给 .category-bar 加 .is-scrollable,
1205
+ mask 只作用于滚动区,让最后一个 pill 右缘淡出提示可滑;「更多」固定显示 */
1206
+ .bar-more {
1207
+ flex: none;
1208
+ }
1209
+ .bar-more-arrow {
1210
+ width: 14px;
1211
+ height: 14px;
1212
+ }
1213
+ .category-bar.is-scrollable .bar-scroll {
1214
+ -webkit-mask-image: linear-gradient(
1215
+ to right,
1216
+ #000 calc(100% - 36px),
1217
+ transparent
1218
+ );
1219
+ mask-image: linear-gradient(to right, #000 calc(100% - 36px), transparent);
1220
+ }
1221
+
1222
+ /* sidebar */
1223
+ /* §4.45:min-width:0 阻断子内容 min-content 沿 grid/flex 链向上撑宽,
1224
+ 保证侧栏宽度恒定(内容在卡片内截断,而非卡片被内容撑动)
1225
+ §4.50:align-self:stretch 拉伸 aside 至行轨道高度(父级 align-items:start 不拉伸 item),
1226
+ 为 .side-sticky 提供粘性活动空间;display 改 flex column,防止内部行被 stretch 拉伸撑大组间距 */
1227
+ .sidebar {
1228
+ display: flex;
1229
+ flex-direction: column;
1230
+ gap: 20px;
1231
+ min-width: 0;
1232
+ align-self: stretch;
1233
+ }
1234
+ /* §4.50 position 分组容器(top/sticky 双组):组内卡片间距保持 20px 节奏 */
1235
+ .side-top,
1236
+ .side-sticky {
1237
+ display: grid;
1238
+ gap: 20px;
1239
+ min-width: 0;
1240
+ }
1241
+ /* §4.50 sticky 组:≥768px 吸附于 sticky header 下方跟随滚动
1242
+ (top 间距对齐独立 toc 的 calc(var(--header-h) + 24px));移动端平铺无 sticky */
1243
+ @media (min-width: 768px) {
1244
+ .side-sticky {
1245
+ position: sticky;
1246
+ top: calc(var(--header-h) + 24px);
1247
+ }
1248
+ }
1249
+ /* §4.49 移动端差异化侧栏:<768px 隐藏 hideOnMobile 的 widget(默认 toc/calendar 隐藏)。
1250
+ 参照 orchid-blog「移动端独立组件列表 + md 断点显隐」机制,此处用单 DOM + 显隐位等价实现 */
1251
+ @media (max-width: 767px) {
1252
+ .side-hide-m {
1253
+ display: none !important;
1254
+ }
1255
+ }
1256
+ /* §4.46 对齐参考站:内边距收窄至 16px、圆角 16px(scoped 覆盖,不动全局 --radius),
1257
+ 白卡贴边更舒展、视觉上更宽 */
1258
+ .side-card {
1259
+ padding: 20px 16px;
1260
+ border-radius: 16px;
1261
+ min-width: 0;
1262
+ max-width: 100%;
1263
+ }
1264
+ /* §4.46 对齐参考站 WidgetLayout 标题:text-lg font-bold + 主题色竖条 before:w-1 h-4 */
1265
+ .side-card h3 {
1266
+ display: flex;
1267
+ align-items: center;
1268
+ gap: 8px;
1269
+ font-size: 16px;
1270
+ font-weight: 600;
1271
+ letter-spacing: 0.05em;
1272
+ color: var(--ink);
1273
+ margin-bottom: 12px;
1274
+ }
1275
+ .side-card h3::before {
1276
+ content: "";
1277
+ width: 4px;
1278
+ height: 16px;
1279
+ border-radius: 2px;
1280
+ background: var(--accent);
1281
+ flex: none;
1282
+ }
1283
+ .side-card p {
1284
+ font-size: 14px;
1285
+ color: var(--ink-2);
1286
+ }
1287
+ .cat-list {
1288
+ display: grid;
1289
+ gap: 8px;
1290
+ font-size: 14px;
1291
+ }
1292
+ .cat-list a {
1293
+ display: flex;
1294
+ justify-content: space-between;
1295
+ /* §4.46 对齐参考站条目加粗层级 */
1296
+ font-weight: 600;
1297
+ color: var(--ink-2);
1298
+ }
1299
+ .cat-list a:hover {
1300
+ color: var(--accent-ink);
1301
+ }
1302
+ .cat-list .count {
1303
+ color: var(--muted);
1304
+ font-variant-numeric: tabular-nums;
1305
+ }
1306
+ /* 个人资料卡(§4.55):对齐参考项目——全宽大头像 + hover 遮罩 + 居中名字/装饰条/简介 + 居中按钮组 */
1307
+ .profile-avatar-link {
1308
+ display: block;
1309
+ position: relative;
1310
+ overflow: hidden;
1311
+ border-radius: 12px;
1312
+ }
1313
+ .profile-avatar-link::after {
1314
+ content: "";
1315
+ position: absolute;
1316
+ inset: 0;
1317
+ background: rgba(0, 0, 0, 0);
1318
+ transition: background 0.2s;
1319
+ }
1320
+ .profile-avatar-link:hover::after {
1321
+ background: rgba(0, 0, 0, 0.25);
1322
+ }
1323
+ .profile-avatar {
1324
+ display: block;
1325
+ width: 100%;
1326
+ aspect-ratio: 1 / 1;
1327
+ object-fit: cover;
1328
+ border: 1px solid var(--border);
1329
+ border-radius: 12px;
1330
+ }
1331
+ .profile-id {
1332
+ display: grid;
1333
+ gap: 7px;
1334
+ justify-items: center;
1335
+ margin-top: 14px;
1336
+ }
1337
+ .profile-name {
1338
+ font-family: var(--font-display);
1339
+ font-size: 20px;
1340
+ font-weight: 700;
1341
+ text-align: center;
1342
+ color: var(--ink);
1343
+ }
1344
+ a.profile-name:hover {
1345
+ color: var(--accent-deep);
1346
+ }
1347
+ html.dark a.profile-name:hover {
1348
+ color: var(--accent);
1349
+ }
1350
+ .profile-bar {
1351
+ width: 20px;
1352
+ height: 4px;
1353
+ border-radius: 2px;
1354
+ background: var(--accent);
1355
+ }
1356
+ .profile-bio {
1357
+ margin-top: 10px;
1358
+ font-size: 13.5px;
1359
+ line-height: 1.7;
1360
+ text-align: center;
1361
+ color: var(--muted);
1362
+ }
1363
+ .profile-links {
1364
+ display: flex;
1365
+ flex-wrap: wrap;
1366
+ justify-content: center;
1367
+ gap: 8px;
1368
+ margin-top: 14px;
1369
+ }
1370
+ .profile-links a {
1371
+ display: inline-flex;
1372
+ align-items: center;
1373
+ justify-content: center;
1374
+ gap: 6px;
1375
+ height: 40px;
1376
+ padding: 0 12px;
1377
+ border-radius: 10px;
1378
+ background: var(--bg-soft);
1379
+ font-size: 13px;
1380
+ color: var(--ink-2);
1381
+ transition:
1382
+ color 0.15s,
1383
+ background 0.15s;
1384
+ }
1385
+ .profile-links a:hover {
1386
+ color: var(--accent-ink);
1387
+ background: var(--accent-soft);
1388
+ }
1389
+ .profile-link-icon {
1390
+ display: inline-flex;
1391
+ width: 20px;
1392
+ height: 20px;
1393
+ }
1394
+ .profile-link-icon svg {
1395
+ width: 100%;
1396
+ height: 100%;
1397
+ }
1398
+ .side-tags {
1399
+ display: flex;
1400
+ flex-wrap: wrap;
1401
+ gap: 8px;
1402
+ }
1403
+ /* §4.48 标签卡「…更多」入口:虚线边框弱化与常规 chip 区分,点击进标签页 */
1404
+ .chip-more {
1405
+ border-style: dashed;
1406
+ color: var(--muted);
1407
+ }
1408
+ .side-friends {
1409
+ display: grid;
1410
+ gap: 9px;
1411
+ }
1412
+ /* 侧栏公告(M3b-b3):content 支持 \n 换行展示 */
1413
+ .side-announcement {
1414
+ white-space: pre-line;
1415
+ }
1416
+ .side-announcement-foot {
1417
+ display: flex;
1418
+ align-items: center;
1419
+ justify-content: space-between;
1420
+ gap: 10px;
1421
+ margin-top: 12px;
1422
+ }
1423
+ .side-close {
1424
+ width: 26px;
1425
+ height: 26px;
1426
+ flex: none;
1427
+ border-radius: 8px;
1428
+ border: 1px solid var(--border);
1429
+ background: transparent;
1430
+ color: var(--muted);
1431
+ font-size: 12px;
1432
+ line-height: 1;
1433
+ cursor: pointer;
1434
+ transition:
1435
+ color 0.15s,
1436
+ border-color 0.15s,
1437
+ background 0.15s;
1438
+ }
1439
+ .side-close:hover {
1440
+ color: var(--accent-ink);
1441
+ border-color: var(--accent);
1442
+ background: var(--accent-soft);
1443
+ }
1444
+ /* 侧栏广告位(M3b-b3):关闭钮默认隐身,hover 卡片淡入 */
1445
+ .advertisement-widget {
1446
+ position: relative;
1447
+ }
1448
+ .ad-close {
1449
+ position: absolute;
1450
+ top: 10px;
1451
+ right: 10px;
1452
+ width: 24px;
1453
+ height: 24px;
1454
+ border-radius: 50%;
1455
+ border: 1px solid var(--border);
1456
+ background: var(--surface);
1457
+ color: var(--muted);
1458
+ font-size: 11px;
1459
+ line-height: 1;
1460
+ cursor: pointer;
1461
+ opacity: 0;
1462
+ transition: opacity 0.2s;
1463
+ }
1464
+ .advertisement-widget:hover .ad-close,
1465
+ .ad-close:focus-visible {
1466
+ opacity: 1;
1467
+ }
1468
+ .ad-close:hover {
1469
+ color: var(--accent-ink);
1470
+ border-color: var(--accent);
1471
+ }
1472
+ .ad-body {
1473
+ display: grid;
1474
+ gap: 10px;
1475
+ justify-items: center;
1476
+ text-align: center;
1477
+ }
1478
+ .ad-body img {
1479
+ width: 100%;
1480
+ height: auto;
1481
+ border-radius: 10px;
1482
+ border: 1px solid var(--border);
1483
+ }
1484
+ .side-friends a {
1485
+ display: flex;
1486
+ align-items: center;
1487
+ gap: 10px;
1488
+ font-size: 13.5px;
1489
+ color: var(--ink-2);
1490
+ }
1491
+ .side-friends a:hover {
1492
+ color: var(--accent-deep);
1493
+ }
1494
+ html.dark .side-friends a:hover {
1495
+ color: var(--accent);
1496
+ }
1497
+ .side-friends img {
1498
+ width: 24px;
1499
+ height: 24px;
1500
+ border-radius: 50%;
1501
+ border: 1px solid var(--border);
1502
+ }
1503
+ .side-more {
1504
+ display: inline-block;
1505
+ margin-top: 12px;
1506
+ font-size: 13px;
1507
+ }
1508
+ .site-info {
1509
+ display: grid;
1510
+ gap: 8px;
1511
+ font-size: 14px;
1512
+ color: var(--ink-2);
1513
+ }
1514
+ .site-info b {
1515
+ font-weight: 600;
1516
+ color: var(--ink);
1517
+ font-variant-numeric: tabular-nums;
1518
+ }
1519
+ .site-info .row {
1520
+ display: flex;
1521
+ justify-content: space-between;
1522
+ }
1523
+
1524
+ /* 日历 widget(月视图 + 活跃度热力图) */
1525
+ /* §4.45:宽度恒定——<qy-calendar> 无 class,选择器用标签名;
1526
+ 自定义元素默认 display:inline(宽度随内容 shrink-to-fit),文章标题 min-content
1527
+ 会沿 inline/flex 链向上撑宽卡片,导致侧栏宽度随列表有无文章/标题长短变动;
1528
+ display:block + min-width:0 + max-width:100% 斩断传播,列表在固定宽度内截断 */
1529
+ qy-calendar {
1530
+ --cal-cell: 13px;
1531
+ display: block;
1532
+ min-width: 0;
1533
+ max-width: 100%;
1534
+ }
1535
+ .cal-head {
1536
+ display: flex;
1537
+ align-items: center;
1538
+ justify-content: space-between;
1539
+ margin-bottom: 10px;
1540
+ }
1541
+ /* §4.47 年月标签改为可点按钮:加粗加大 + 悬停/展开态,▾ 提示可开合年月选择器
1542
+ §4.54 极简不是小家子气:日期与箭头控件整体放大一档,重置按钮移至日期 ▾ 之后 */
1543
+ .cal-month {
1544
+ font-size: 17px;
1545
+ font-weight: 700;
1546
+ color: var(--ink);
1547
+ font-variant-numeric: tabular-nums;
1548
+ font-family: inherit;
1549
+ background: transparent;
1550
+ border: 0;
1551
+ padding: 4px 12px;
1552
+ border-radius: 8px;
1553
+ cursor: pointer;
1554
+ user-select: none;
1555
+ transition:
1556
+ background 0.15s ease,
1557
+ color 0.15s ease;
1558
+ }
1559
+ .cal-month::after {
1560
+ content: "▾";
1561
+ display: inline-block;
1562
+ font-size: 12px;
1563
+ margin-left: 6px;
1564
+ color: var(--muted);
1565
+ transition: transform 0.15s ease;
1566
+ }
1567
+ .cal-month:hover {
1568
+ background: var(--bg-soft);
1569
+ }
1570
+ .cal-month.open {
1571
+ color: var(--accent);
1572
+ background: var(--accent-soft);
1573
+ }
1574
+ .cal-month.open::after {
1575
+ transform: rotate(180deg);
1576
+ }
1577
+ .cal-head-r {
1578
+ display: flex;
1579
+ align-items: center;
1580
+ gap: 4px;
1581
+ }
1582
+ /* §4.54 日期 + 重置按钮成组居中(重置紧跟日期 ▾ 之后) */
1583
+ .cal-head-c {
1584
+ display: flex;
1585
+ align-items: center;
1586
+ gap: 6px;
1587
+ }
1588
+ /* §4.47 翻月/回当月/年步进按钮统一外观(§4.54 放大一档):
1589
+ 结构简化后由「.cal-nav button 后代选择器」改为类直配(.cal-nav/.cal-home/.cal-py) */
1590
+ .cal-nav,
1591
+ .cal-home,
1592
+ .cal-py {
1593
+ width: 28px;
1594
+ height: 28px;
1595
+ display: grid;
1596
+ place-items: center;
1597
+ border: 1px solid var(--border);
1598
+ border-radius: 8px;
1599
+ background: transparent;
1600
+ color: var(--muted);
1601
+ font-size: 16px;
1602
+ line-height: 1;
1603
+ font-family: inherit;
1604
+ cursor: pointer;
1605
+ transition:
1606
+ color 0.2s ease,
1607
+ border-color 0.2s ease;
1608
+ }
1609
+ .cal-nav:hover:not(:disabled),
1610
+ .cal-home:hover:not(:disabled),
1611
+ .cal-py:hover:not(:disabled) {
1612
+ color: var(--accent);
1613
+ border-color: var(--accent);
1614
+ }
1615
+ .cal-nav:disabled,
1616
+ .cal-home:disabled,
1617
+ .cal-py:disabled {
1618
+ opacity: 0.35;
1619
+ cursor: default;
1620
+ }
1621
+ /* §4.47 回到本月按钮:仅非当月渲染,主题色与翻月箭头区分 */
1622
+ .cal-home {
1623
+ color: var(--accent);
1624
+ border-color: currentColor;
1625
+ }
1626
+ /* §4.47 年月选择器:年步进行 + 4 列月网格(未来月置灰、当前浏览月高亮) */
1627
+ .cal-picker {
1628
+ border: 1px solid var(--border);
1629
+ border-radius: 10px;
1630
+ background: var(--bg-soft);
1631
+ padding: 10px;
1632
+ margin-bottom: 10px;
1633
+ }
1634
+ .cal-picker-row {
1635
+ display: flex;
1636
+ align-items: center;
1637
+ justify-content: space-between;
1638
+ margin-bottom: 8px;
1639
+ }
1640
+ .cal-py-label {
1641
+ font-size: 14px;
1642
+ font-weight: 700;
1643
+ color: var(--ink);
1644
+ font-variant-numeric: tabular-nums;
1645
+ }
1646
+ .cal-picker-months {
1647
+ display: grid;
1648
+ grid-template-columns: repeat(4, 1fr);
1649
+ gap: 4px;
1650
+ }
1651
+ .cal-pm {
1652
+ font-size: 11.5px;
1653
+ padding: 5px 0;
1654
+ border: 1px solid var(--border);
1655
+ border-radius: 6px;
1656
+ background: transparent;
1657
+ color: var(--muted);
1658
+ font-family: inherit;
1659
+ font-variant-numeric: tabular-nums;
1660
+ cursor: pointer;
1661
+ transition:
1662
+ color 0.15s ease,
1663
+ border-color 0.15s ease,
1664
+ background 0.15s ease;
1665
+ }
1666
+ .cal-pm:hover:not(:disabled) {
1667
+ color: var(--accent);
1668
+ border-color: var(--accent);
1669
+ }
1670
+ .cal-pm.on {
1671
+ color: var(--accent);
1672
+ border-color: var(--accent);
1673
+ background: var(--accent-soft);
1674
+ font-weight: 600;
1675
+ }
1676
+ .cal-pm:disabled {
1677
+ opacity: 0.35;
1678
+ cursor: default;
1679
+ }
1680
+ .cal-grid {
1681
+ display: grid;
1682
+ grid-template-columns: repeat(7, 1fr);
1683
+ gap: 2px;
1684
+ text-align: center;
1685
+ }
1686
+ .cal-week {
1687
+ font-size: 10.5px;
1688
+ color: var(--muted);
1689
+ padding-bottom: 4px;
1690
+ }
1691
+ .cal-day {
1692
+ position: relative;
1693
+ aspect-ratio: 1;
1694
+ display: grid;
1695
+ place-items: center;
1696
+ font-size: 11px;
1697
+ color: var(--ink-2);
1698
+ border-radius: 6px;
1699
+ font-variant-numeric: tabular-nums;
1700
+ }
1701
+ .cal-day.dim {
1702
+ color: transparent;
1703
+ pointer-events: none;
1704
+ }
1705
+ .cal-day.has-post {
1706
+ background: hsl(var(--accent-h) var(--accent-s) var(--accent-l) / 0.16);
1707
+ color: var(--accent-deep);
1708
+ font-weight: 600;
1709
+ }
1710
+ html.dark .cal-day.has-post {
1711
+ color: var(--accent);
1712
+ }
1713
+ .cal-day.today {
1714
+ outline: 1.5px solid var(--accent);
1715
+ outline-offset: -1.5px;
1716
+ }
1717
+ .cal-heat {
1718
+ /* §4.43:去「活跃度」标题;§4.44 还原 orchid-blog 原版两行结构:月份标签行 + 12×4 格子网格 */
1719
+ margin-top: 12px;
1720
+ }
1721
+ /* 月份标签行(§4.43 数字展示,§4.44 独立一行 grid 12 列,同原版) */
1722
+ .cal-heat-labels {
1723
+ display: grid;
1724
+ grid-template-columns: repeat(12, 1fr);
1725
+ gap: 2px;
1726
+ margin-bottom: 4px;
1727
+ }
1728
+ .cal-heat-label {
1729
+ font-size: 9px;
1730
+ font-weight: 400;
1731
+ line-height: 1;
1732
+ text-align: center;
1733
+ color: var(--muted);
1734
+ }
1735
+ /* 48 个正方形小格子平铺 12×4(§4.44 还原原版:格子 width:85% + aspect-ratio:1 自持正方形,
1736
+ 行高由内容撑起;仅 row-gap 无 column-gap,列间隙由 85% 宽度留出,同原版);
1737
+ 教训:§4.43 曾把 aspect-ratio 放在 <i> 格子上(inline 不生效)且列级外包 div 截断
1738
+ stretch 链,导致格子高 0、热力图塌成 12px——grid item 会被 block 化,
1739
+ 此处显式 display:block 确保 aspect-ratio 生效 */
1740
+ .cal-heat-grid {
1741
+ display: grid;
1742
+ grid-template-columns: repeat(12, 1fr);
1743
+ grid-template-rows: repeat(4, 1fr);
1744
+ row-gap: 2px;
1745
+ }
1746
+ .cal-heat-cell {
1747
+ display: block;
1748
+ width: 85%;
1749
+ aspect-ratio: 1;
1750
+ margin: auto;
1751
+ border-radius: 2px;
1752
+ cursor: pointer;
1753
+ transition: box-shadow 0.15s ease;
1754
+ background: hsl(
1755
+ var(--accent-h) var(--accent-s) var(--accent-l) /
1756
+ max(var(--o, 0), 0.08)
1757
+ );
1758
+ }
1759
+ /* 未来月份格子(§4.44):无 role,不可点击跳月 */
1760
+ .cal-heat-cell:not([role="button"]) {
1761
+ cursor: default;
1762
+ }
1763
+ .cal-heat-cell[role="button"]:hover {
1764
+ box-shadow: 0 0 1px 1.5px hsl(var(--accent-h) var(--accent-s) var(--accent-l));
1765
+ }
1766
+ .cal-heat-cell:focus-visible {
1767
+ outline: 1.5px solid var(--accent);
1768
+ outline-offset: 1px;
1769
+ border-radius: 2px;
1770
+ }
1771
+
1772
+ /* 热力图下方文章列表(§4.40,§4.43 移至热力图下):月视图 → 热力图 → 列表;
1773
+ 默认当月全部,点日期过滤当日;按时间倒序,左标题右日期,超宽标题省略号截断,过长纵向滚动 */
1774
+ /* §4.45:链条加 min-width:0,文章列表在 widget 固定宽度内截断 */
1775
+ .cal-list {
1776
+ margin-top: 10px;
1777
+ display: flex;
1778
+ flex-direction: column;
1779
+ gap: 3px;
1780
+ min-width: 0;
1781
+ }
1782
+ .cal-list-items {
1783
+ display: flex;
1784
+ flex-direction: column;
1785
+ gap: 2px;
1786
+ max-height: 176px;
1787
+ overflow-y: auto;
1788
+ min-width: 0;
1789
+ }
1790
+ .cal-post {
1791
+ display: flex;
1792
+ align-items: baseline;
1793
+ justify-content: space-between;
1794
+ gap: 8px;
1795
+ font-size: 13px;
1796
+ line-height: 1.5;
1797
+ color: var(--ink-2);
1798
+ padding: 4px 8px;
1799
+ border-radius: var(--radius-sm);
1800
+ min-width: 0;
1801
+ }
1802
+ /* 左侧标题:flex:1 1 0 + min-width:0 允许收缩,超宽省略号截断(§4.43/§4.45) */
1803
+ .cal-post-title {
1804
+ flex: 1 1 0;
1805
+ min-width: 0;
1806
+ overflow: hidden;
1807
+ white-space: nowrap;
1808
+ text-overflow: ellipsis;
1809
+ }
1810
+ /* 右侧发布日期:不压缩、弱化色(§4.43) */
1811
+ .cal-post-date {
1812
+ flex-shrink: 0;
1813
+ font-size: 12px;
1814
+ color: var(--muted);
1815
+ }
1816
+ .cal-post:hover {
1817
+ color: var(--accent-ink);
1818
+ background: var(--bg-soft);
1819
+ }
1820
+ /* 有文章的日期可点选(§4.40):选中态实底强调色,与 today 描边叠加可区分 */
1821
+ .cal-day.has-post {
1822
+ cursor: pointer;
1823
+ }
1824
+ .cal-day.sel {
1825
+ background: var(--accent);
1826
+ color: #fff;
1827
+ font-weight: 600;
1828
+ }
1829
+
1830
+ /* 文章页侧栏目录 */
1831
+ .side-toc {
1832
+ display: grid;
1833
+ gap: 2px;
1834
+ }
1835
+ .side-toc a {
1836
+ font-size: 13px;
1837
+ color: var(--ink-2);
1838
+ text-decoration: none;
1839
+ white-space: nowrap;
1840
+ overflow: hidden;
1841
+ text-overflow: ellipsis;
1842
+ padding: 3px 6px;
1843
+ border-radius: 6px;
1844
+ transition:
1845
+ color 0.2s ease,
1846
+ background 0.2s ease;
1847
+ }
1848
+ .side-toc a:hover {
1849
+ color: var(--accent-deep);
1850
+ background: var(--accent-soft);
1851
+ }
1852
+ html.dark .side-toc a:hover {
1853
+ color: var(--accent);
1854
+ }
1855
+ .side-toc .toc-depth-3 {
1856
+ padding-left: 18px;
1857
+ }
1858
+ .side-toc .toc-depth-4 {
1859
+ padding-left: 30px;
1860
+ }
1861
+
1862
+ /* pagination(§4.53 双模式,§4.54 去胶囊改方块、统一宽度多列页码):
1863
+ PC 页码条 .pg-nums,移动端上下页 .pg-adj */
1864
+ .pagination {
1865
+ margin-top: 32px;
1866
+ display: flex;
1867
+ justify-content: center;
1868
+ align-items: center;
1869
+ gap: 14px;
1870
+ font-size: 14px;
1871
+ color: var(--muted);
1872
+ }
1873
+ .page-item {
1874
+ min-width: 38px;
1875
+ padding: 6px 10px;
1876
+ box-sizing: border-box;
1877
+ border: 1px solid var(--border);
1878
+ border-radius: 6px;
1879
+ color: var(--ink-2);
1880
+ background: var(--surface);
1881
+ text-align: center;
1882
+ /* 显式行高(§4.55):箭头与数字页码完全同尺寸 */
1883
+ line-height: 1.5;
1884
+ }
1885
+ a.page-item:hover {
1886
+ border-color: var(--accent);
1887
+ color: var(--accent-ink);
1888
+ }
1889
+ .page-item.disabled {
1890
+ color: var(--muted);
1891
+ opacity: 0.55;
1892
+ cursor: not-allowed;
1893
+ }
1894
+ .pg-nums {
1895
+ display: flex;
1896
+ align-items: center;
1897
+ gap: 6px;
1898
+ flex-wrap: wrap;
1899
+ justify-content: center;
1900
+ }
1901
+ .page-item.current {
1902
+ border-color: var(--accent);
1903
+ background: var(--accent-soft);
1904
+ color: var(--accent-ink);
1905
+ font-weight: 600;
1906
+ }
1907
+ .pg-gap {
1908
+ color: var(--muted);
1909
+ padding: 0 2px;
1910
+ }
1911
+ .pg-adj {
1912
+ display: none;
1913
+ align-items: center;
1914
+ gap: 14px;
1915
+ }
1916
+ @media (max-width: 767px) {
1917
+ .pg-nums {
1918
+ display: none;
1919
+ }
1920
+ .pg-adj {
1921
+ display: flex;
1922
+ }
1923
+ }
1924
+
1925
+ /* ---------- 6. 文章页 ---------- */
1926
+ .post-header {
1927
+ margin: 0 0 28px;
1928
+ }
1929
+ .post-header .chip {
1930
+ margin-bottom: 16px;
1931
+ }
1932
+ .post-title-lg {
1933
+ font-family: var(--font-display);
1934
+ font-size: clamp(26px, 4vw, 36px);
1935
+ font-weight: 700;
1936
+ line-height: 1.4;
1937
+ letter-spacing: 0.02em;
1938
+ }
1939
+ .post-header .post-meta {
1940
+ margin-top: 16px;
1941
+ }
1942
+ /* meta 区图标化(§4.14,参考 orchid-blog PostMeta):图标 + 文本同行 */
1943
+ .post-meta .meta-item {
1944
+ display: inline-flex;
1945
+ align-items: center;
1946
+ gap: 5px;
1947
+ }
1948
+ .post-meta .meta-item svg {
1949
+ width: 14px;
1950
+ height: 14px;
1951
+ flex-shrink: 0;
1952
+ opacity: 0.85;
1953
+ }
1954
+ /* 分类/标签内联链接(§4.22,对齐 orchid-blog):文字链接 + 「/」分隔 */
1955
+ .post-meta .meta-item a {
1956
+ color: inherit;
1957
+ text-decoration: none;
1958
+ white-space: nowrap;
1959
+ transition: color 0.15s;
1960
+ }
1961
+ .post-meta .meta-item a:hover {
1962
+ color: var(--accent-ink);
1963
+ }
1964
+ .post-meta .tag-sep {
1965
+ color: var(--muted);
1966
+ opacity: 0.6;
1967
+ }
1968
+ /* 标签较多时组内换行(行间收紧),整组仍作为一项参与 meta 行换行 */
1969
+ .post-meta .meta-tags-item {
1970
+ flex-wrap: wrap;
1971
+ row-gap: 2px;
1972
+ }
1973
+ .article-cover {
1974
+ position: relative;
1975
+ margin: 0 0 36px;
1976
+ border-radius: var(--radius);
1977
+ overflow: hidden;
1978
+ border: 1px solid var(--border);
1979
+ box-shadow: var(--shadow-sm);
1980
+ cursor: zoom-in;
1981
+ }
1982
+ .article-cover img {
1983
+ width: 100%;
1984
+ aspect-ratio: 16 / 9;
1985
+ object-fit: cover;
1986
+ }
1987
+ .article-cover figcaption {
1988
+ padding: 10px 16px;
1989
+ font-size: 13px;
1990
+ color: var(--muted);
1991
+ text-align: center;
1992
+ background: var(--surface);
1993
+ }
1994
+
1995
+ /* 左右两栏:≥768px 正文列 + 侧栏列(对齐参考模板 md 断点),≤767px 单列堆叠 */
1996
+ .post-layout {
1997
+ display: grid;
1998
+ grid-template-columns: minmax(0, 1fr);
1999
+ gap: 36px;
2000
+ align-items: start;
2001
+ max-width: 900px;
2002
+ margin: 0 auto;
2003
+ }
2004
+ .post-main {
2005
+ /* min-width:0 防 nowrap 标题/代码撑破网格轨道 */
2006
+ min-width: 0;
2007
+ }
2008
+ @media (min-width: 768px) {
2009
+ .post-layout {
2010
+ grid-template-columns: minmax(0, 1fr) 280px;
2011
+ /* §4.46 侧栏统一 280px(与首页一致),max-width 同步 +60px 保持正文阅读行宽不变(§4.32 迭代) */
2012
+ max-width: 1180px;
2013
+ }
2014
+ }
2015
+ .prose {
2016
+ font-size: 16.5px;
2017
+ color: var(--ink);
2018
+ /* 长英文词/URL 换行(§4.13):防撑破窄屏容器 */
2019
+ overflow-wrap: break-word;
2020
+ }
2021
+ .prose > * + * {
2022
+ margin-top: 1em;
2023
+ }
2024
+ .prose h2 {
2025
+ font-family: var(--font-display);
2026
+ font-size: 24px;
2027
+ font-weight: 700;
2028
+ margin-top: 2em;
2029
+ padding-bottom: 0.4em;
2030
+ border-bottom: 1px solid var(--border);
2031
+ scroll-margin-top: calc(var(--header-h) + 20px);
2032
+ }
2033
+ .prose h3 {
2034
+ font-family: var(--font-display);
2035
+ font-size: 19px;
2036
+ font-weight: 700;
2037
+ margin-top: 1.8em;
2038
+ scroll-margin-top: calc(var(--header-h) + 20px);
2039
+ }
2040
+ .prose h4 {
2041
+ font-family: var(--font-display);
2042
+ font-size: 16.5px;
2043
+ font-weight: 700;
2044
+ margin-top: 1.6em;
2045
+ scroll-margin-top: calc(var(--header-h) + 20px);
2046
+ }
2047
+ .prose blockquote {
2048
+ padding: 12px 20px;
2049
+ border-left: 3px solid var(--accent);
2050
+ background: var(--accent-soft);
2051
+ border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
2052
+ color: var(--accent-ink);
2053
+ }
2054
+ html.dark .prose blockquote {
2055
+ color: var(--ink-2);
2056
+ }
2057
+ .prose ul,
2058
+ .prose ol {
2059
+ padding-left: 1.6em;
2060
+ }
2061
+ .prose li + li {
2062
+ margin-top: 0.35em;
2063
+ }
2064
+ .prose li::marker {
2065
+ color: var(--accent);
2066
+ }
2067
+ .prose code:not(pre code) {
2068
+ font-family: var(--font-mono);
2069
+ font-size: 0.88em;
2070
+ padding: 2px 7px;
2071
+ border-radius: 6px;
2072
+ background: var(--bg-soft);
2073
+ border: 1px solid var(--border);
2074
+ color: var(--accent-ink);
2075
+ }
2076
+ /* 代码块(§4.61 起由 Expressive Code 接管):EC 自带完整样式(useStyleReset
2077
+ all:revert 防站点样式干扰)与复制/折叠/行号交互,双主题选择器为
2078
+ html.dark / html:not(.dark),随 codeTheme 配置内联进首个代码块输出 */
2079
+ /* 折叠插件样式修复(§4.62):EC 内联插件 baseStyles 时统一加 .expressive-code
2080
+ 祖先前缀,而 expressive-code-collapsible 把折叠按钮/渐隐层/内容包装渲染在
2081
+ figure.expressive-code 之外(.ec-collapse 直下),前缀选择器永不命中——按钮失去
2082
+ absolute 定位与命中区域,真实点击无法展开。此处按插件原语义补不带前缀的等价规则;
2083
+ 渐隐底色与 codeTheme 双主题(github-light/github-dark)默认代码底色一致,换色需同步 */
2084
+ .ec-collapse {
2085
+ position: relative;
2086
+ --ec-collapse-bg-color: #fff;
2087
+ --ec-collapse-accent-color: var(--accent);
2088
+ }
2089
+ html.dark .ec-collapse {
2090
+ --ec-collapse-bg-color: #24292e;
2091
+ }
2092
+ .ec-collapse__content {
2093
+ position: relative;
2094
+ }
2095
+ .ec-collapse.ec-collapse--collapsed .ec-collapse__content {
2096
+ max-height: var(--ec-collapse-preview-height, 280px);
2097
+ overflow: hidden;
2098
+ }
2099
+ .ec-collapse.ec-collapse--expanded .ec-collapse__content {
2100
+ max-height: none;
2101
+ }
2102
+ .ec-collapse__gradient {
2103
+ position: absolute;
2104
+ bottom: 0;
2105
+ left: 0;
2106
+ right: 0;
2107
+ height: 80px;
2108
+ background: linear-gradient(
2109
+ to bottom,
2110
+ transparent 0%,
2111
+ var(--ec-collapse-bg-color) 100%
2112
+ );
2113
+ pointer-events: none;
2114
+ opacity: 1;
2115
+ transition: opacity 0.3s ease;
2116
+ z-index: 10;
2117
+ }
2118
+ .ec-collapse.ec-collapse--expanded .ec-collapse__gradient {
2119
+ opacity: 0;
2120
+ pointer-events: none;
2121
+ }
2122
+ .ec-collapse__toggle {
2123
+ display: flex;
2124
+ align-items: center;
2125
+ justify-content: center;
2126
+ gap: 6px;
2127
+ margin: 0 auto;
2128
+ padding: 6px 16px;
2129
+ background-color: rgba(0, 0, 0, 0.05);
2130
+ border: 1px solid rgba(0, 0, 0, 0.15);
2131
+ border-radius: 20px;
2132
+ color: var(--ec-collapse-accent-color);
2133
+ font-size: 0.85rem;
2134
+ font-weight: 500;
2135
+ cursor: pointer;
2136
+ transition:
2137
+ background-color 0.2s ease,
2138
+ border-color 0.2s ease;
2139
+ }
2140
+ .ec-collapse.ec-collapse--collapsed .ec-collapse__toggle {
2141
+ position: absolute;
2142
+ bottom: 12px;
2143
+ left: 50%;
2144
+ transform: translateX(-50%);
2145
+ z-index: 20;
2146
+ margin: 0;
2147
+ }
2148
+ .ec-collapse.ec-collapse--expanded .ec-collapse__toggle {
2149
+ position: relative;
2150
+ margin: 12px auto;
2151
+ }
2152
+ .ec-collapse__toggle:hover {
2153
+ background-color: rgba(0, 0, 0, 0.08);
2154
+ border-color: rgba(0, 0, 0, 0.25);
2155
+ }
2156
+ html.dark .ec-collapse__toggle {
2157
+ background-color: rgba(255, 255, 255, 0.1);
2158
+ border-color: rgba(255, 255, 255, 0.2);
2159
+ }
2160
+ html.dark .ec-collapse__toggle:hover {
2161
+ background-color: rgba(255, 255, 255, 0.15);
2162
+ border-color: rgba(255, 255, 255, 0.3);
2163
+ }
2164
+ .ec-collapse__toggle:focus-visible {
2165
+ outline: 2px solid var(--ec-collapse-accent-color);
2166
+ outline-offset: 2px;
2167
+ }
2168
+ .ec-collapse__icon {
2169
+ transition: transform 0.3s ease;
2170
+ }
2171
+ .ec-collapse.ec-collapse--expanded .ec-collapse__icon {
2172
+ transform: rotate(180deg);
2173
+ }
2174
+ .ec-collapse__text-collapse {
2175
+ display: none;
2176
+ }
2177
+ .ec-collapse.ec-collapse--expanded .ec-collapse__text-expand {
2178
+ display: none;
2179
+ }
2180
+ .ec-collapse.ec-collapse--expanded .ec-collapse__text-collapse {
2181
+ display: inline;
2182
+ }
2183
+ @media (prefers-reduced-motion: reduce) {
2184
+ .ec-collapse__gradient,
2185
+ .ec-collapse__toggle,
2186
+ .ec-collapse__icon {
2187
+ transition: none;
2188
+ }
2189
+ }
2190
+ /* 宽表滚动容器化(§4.13):display:block + overflow-x:auto,多列宽表窄屏内滚不撑破页面 */
2191
+ .prose table {
2192
+ display: block;
2193
+ width: max-content;
2194
+ max-width: 100%;
2195
+ overflow-x: auto;
2196
+ border-collapse: collapse;
2197
+ font-size: 14.5px;
2198
+ }
2199
+ .prose th,
2200
+ .prose td {
2201
+ padding: 9px 14px;
2202
+ text-align: left;
2203
+ border-bottom: 1px solid var(--border);
2204
+ }
2205
+ .prose th {
2206
+ font-weight: 600;
2207
+ color: var(--muted);
2208
+ font-size: 13px;
2209
+ letter-spacing: 0.04em;
2210
+ background: var(--bg-soft);
2211
+ }
2212
+ .prose figure {
2213
+ margin: 0;
2214
+ border-radius: var(--radius-sm);
2215
+ overflow: hidden;
2216
+ border: 1px solid var(--border);
2217
+ }
2218
+ .prose figure img {
2219
+ width: 100%;
2220
+ }
2221
+ .prose figcaption {
2222
+ padding: 8px 14px;
2223
+ font-size: 13px;
2224
+ color: var(--muted);
2225
+ text-align: center;
2226
+ background: var(--surface);
2227
+ }
2228
+ .prose hr {
2229
+ border: none;
2230
+ border-top: 1px dashed var(--border-2);
2231
+ margin: 2em 0;
2232
+ }
2233
+ .prose a {
2234
+ border-bottom: 1px solid var(--accent);
2235
+ }
2236
+ /* 标题锚点(原型无,hover 显形) */
2237
+ .prose .h-anchor {
2238
+ margin-left: 8px;
2239
+ opacity: 0;
2240
+ font-weight: 400;
2241
+ border-bottom: none;
2242
+ transition: opacity 0.15s;
2243
+ }
2244
+ .prose h2:hover .h-anchor,
2245
+ .prose h3:hover .h-anchor,
2246
+ .prose h4:hover .h-anchor {
2247
+ opacity: 0.55;
2248
+ }
2249
+ .callout {
2250
+ display: flex;
2251
+ gap: 12px;
2252
+ padding: 14px 18px;
2253
+ border-radius: var(--radius-sm);
2254
+ font-size: 15px;
2255
+ line-height: 1.7;
2256
+ border: 1px solid var(--border);
2257
+ background: var(--bg-soft);
2258
+ }
2259
+ .callout .co-icon {
2260
+ flex: none;
2261
+ width: 20px;
2262
+ height: 20px;
2263
+ margin-top: 3px;
2264
+ }
2265
+ .callout.info {
2266
+ border-color: hsl(var(--accent-h) 30% 60% / 0.5);
2267
+ background: var(--accent-soft);
2268
+ }
2269
+ .callout.tip {
2270
+ border-color: hsl(var(--accent-h) 30% 60% / 0.5);
2271
+ background: var(--accent-soft);
2272
+ }
2273
+ .callout.important {
2274
+ border-color: hsl(262 60% 60% / 0.45);
2275
+ background: hsl(262 55% 94%);
2276
+ }
2277
+ html.dark .callout.important {
2278
+ background: hsl(262 30% 18%);
2279
+ }
2280
+ .callout.warn {
2281
+ border-color: hsl(38 60% 55% / 0.45);
2282
+ background: hsl(38 55% 92%);
2283
+ }
2284
+ html.dark .callout.warn {
2285
+ background: hsl(38 30% 16%);
2286
+ }
2287
+ .callout.danger {
2288
+ border-color: hsl(2 60% 55% / 0.45);
2289
+ background: hsl(2 55% 95%);
2290
+ }
2291
+ html.dark .callout.danger {
2292
+ background: hsl(2 30% 16%);
2293
+ }
2294
+ .callout.success {
2295
+ border-color: hsl(142 55% 45% / 0.45);
2296
+ background: hsl(142 50% 93%);
2297
+ }
2298
+ html.dark .callout.success {
2299
+ background: hsl(142 30% 15%);
2300
+ }
2301
+ .callout.quote {
2302
+ border-color: var(--border-2);
2303
+ background: var(--bg-soft);
2304
+ }
2305
+ .callout b {
2306
+ display: block;
2307
+ margin-bottom: 2px;
2308
+ }
2309
+ .callout p {
2310
+ color: var(--ink-2);
2311
+ }
2312
+
2313
+ /* toc */
2314
+ .toc {
2315
+ position: sticky;
2316
+ top: calc(var(--header-h) + 24px);
2317
+ display: none;
2318
+ font-size: 13.5px;
2319
+ }
2320
+ @media (min-width: 768px) {
2321
+ .toc {
2322
+ display: block;
2323
+ }
2324
+ }
2325
+ .toc-title {
2326
+ font-size: 12px;
2327
+ letter-spacing: 0.12em;
2328
+ color: var(--muted);
2329
+ margin-bottom: 10px;
2330
+ }
2331
+ .toc a {
2332
+ display: block;
2333
+ padding: 5px 0 5px 14px;
2334
+ color: var(--ink-2);
2335
+ border-left: 2px solid var(--border);
2336
+ line-height: 1.5;
2337
+ transition:
2338
+ color 0.15s,
2339
+ border-color 0.15s;
2340
+ }
2341
+ .toc a:hover {
2342
+ color: var(--ink);
2343
+ }
2344
+ .toc a.is-active {
2345
+ color: var(--accent-ink);
2346
+ border-left-color: var(--accent);
2347
+ font-weight: 500;
2348
+ }
2349
+
2350
+ /* post footer */
2351
+ /* outdated-card(§4.11 文章过时提醒):琥珀色警示调,与卡片设计语言一致 */
2352
+ .outdated-card {
2353
+ margin-top: 36px;
2354
+ display: flex;
2355
+ align-items: flex-start;
2356
+ gap: 12px;
2357
+ padding: 14px 18px;
2358
+ font-size: 13.5px;
2359
+ line-height: 1.7;
2360
+ color: hsl(30 22% 40%);
2361
+ border: 1px solid hsl(38 55% 78%);
2362
+ border-radius: var(--radius-sm);
2363
+ background: hsl(40 60% 95%);
2364
+ }
2365
+ .outdated-icon {
2366
+ flex: none;
2367
+ display: grid;
2368
+ place-items: center;
2369
+ width: 30px;
2370
+ height: 30px;
2371
+ border-radius: var(--radius-sm);
2372
+ color: hsl(28 60% 42%);
2373
+ background: hsl(38 70% 87%);
2374
+ }
2375
+ .outdated-line {
2376
+ color: var(--muted);
2377
+ }
2378
+ .outdated-line strong,
2379
+ .outdated-days {
2380
+ color: inherit;
2381
+ }
2382
+ .outdated-warning {
2383
+ margin-top: 4px;
2384
+ font-weight: 600;
2385
+ color: hsl(28 55% 44%);
2386
+ }
2387
+ html.dark .outdated-card {
2388
+ color: hsl(38 22% 74%);
2389
+ border-color: hsl(38 25% 28%);
2390
+ background: hsl(38 22% 15%);
2391
+ }
2392
+ html.dark .outdated-icon {
2393
+ color: hsl(38 65% 72%);
2394
+ background: hsl(38 25% 22%);
2395
+ }
2396
+ html.dark .outdated-warning {
2397
+ color: hsl(38 65% 66%);
2398
+ }
2399
+ .license {
2400
+ margin-top: 36px;
2401
+ padding: 14px 18px;
2402
+ font-size: 13.5px;
2403
+ color: var(--muted);
2404
+ border: 1px dashed var(--border-2);
2405
+ border-radius: var(--radius-sm);
2406
+ background: var(--bg-soft);
2407
+ }
2408
+ .post-nav {
2409
+ margin-top: 24px;
2410
+ display: grid;
2411
+ gap: 12px;
2412
+ grid-template-columns: 1fr 1fr;
2413
+ }
2414
+ .post-nav a,
2415
+ .post-nav .pn-disabled {
2416
+ display: block;
2417
+ padding: 14px 18px;
2418
+ border-radius: var(--radius-sm);
2419
+ border: 1px solid var(--border);
2420
+ background: var(--surface);
2421
+ }
2422
+ .post-nav a:hover {
2423
+ border-color: var(--accent);
2424
+ }
2425
+ .post-nav .pn-label {
2426
+ font-size: 12px;
2427
+ color: var(--muted);
2428
+ letter-spacing: 0.1em;
2429
+ }
2430
+ .post-nav .pn-title {
2431
+ margin-top: 4px;
2432
+ font-weight: 600;
2433
+ font-size: 14.5px;
2434
+ color: var(--ink);
2435
+ }
2436
+ .post-nav a:hover .pn-title {
2437
+ color: var(--accent-ink);
2438
+ }
2439
+ .post-nav .next {
2440
+ text-align: right;
2441
+ }
2442
+ .post-nav .pn-disabled {
2443
+ opacity: 0.55;
2444
+ }
2445
+
2446
+ /* comments(M3b Artalk 启用) */
2447
+ .comments {
2448
+ margin-top: 44px;
2449
+ }
2450
+ .comments-list {
2451
+ display: grid;
2452
+ gap: 18px;
2453
+ }
2454
+ .comment {
2455
+ display: flex;
2456
+ gap: 14px;
2457
+ padding: 16px 18px;
2458
+ }
2459
+ .comment-avatar {
2460
+ flex: none;
2461
+ width: 42px;
2462
+ height: 42px;
2463
+ border-radius: 50%;
2464
+ overflow: hidden;
2465
+ border: 1px solid var(--border);
2466
+ }
2467
+ .comment-avatar img {
2468
+ width: 100%;
2469
+ height: 100%;
2470
+ object-fit: cover;
2471
+ }
2472
+ .comment-main {
2473
+ flex: 1;
2474
+ min-width: 0;
2475
+ }
2476
+ .comment-head {
2477
+ display: flex;
2478
+ align-items: baseline;
2479
+ gap: 10px;
2480
+ }
2481
+ .comment-author {
2482
+ font-weight: 600;
2483
+ font-size: 14.5px;
2484
+ }
2485
+ .comment-author.owner {
2486
+ color: var(--accent-ink);
2487
+ }
2488
+ .comment-time {
2489
+ font-size: 12.5px;
2490
+ color: var(--muted);
2491
+ }
2492
+ .comment-content {
2493
+ margin-top: 4px;
2494
+ font-size: 15px;
2495
+ color: var(--ink-2);
2496
+ overflow-wrap: break-word;
2497
+ }
2498
+ .comment-reply {
2499
+ margin-top: 14px;
2500
+ padding-left: 14px;
2501
+ border-left: 2px solid var(--border);
2502
+ display: grid;
2503
+ gap: 12px;
2504
+ }
2505
+ .comment-form {
2506
+ margin-top: 24px;
2507
+ padding: 20px 22px;
2508
+ }
2509
+ .comment-form h3 {
2510
+ font-size: 15px;
2511
+ margin-bottom: 14px;
2512
+ font-family: var(--font-display);
2513
+ }
2514
+ .form-grid {
2515
+ display: grid;
2516
+ gap: 12px;
2517
+ }
2518
+ .form-grid input,
2519
+ .form-grid textarea {
2520
+ width: 100%;
2521
+ padding: 10px 14px;
2522
+ border-radius: var(--radius-sm);
2523
+ border: 1px solid var(--border-2);
2524
+ background: var(--bg);
2525
+ color: var(--ink);
2526
+ transition:
2527
+ border-color 0.15s,
2528
+ box-shadow 0.15s;
2529
+ resize: vertical;
2530
+ }
2531
+ .form-grid input:focus,
2532
+ .form-grid textarea:focus {
2533
+ outline: none;
2534
+ border-color: var(--accent);
2535
+ box-shadow: 0 0 0 3px var(--accent-soft);
2536
+ }
2537
+ .form-grid .input-error {
2538
+ border-color: #c0564f;
2539
+ box-shadow: 0 0 0 3px hsl(2 45% 90%);
2540
+ }
2541
+ html.dark .form-grid .input-error {
2542
+ box-shadow: 0 0 0 3px hsl(2 45% 25%);
2543
+ }
2544
+ .form-error {
2545
+ font-size: 13px;
2546
+ color: #c0564f;
2547
+ min-height: 1.4em;
2548
+ }
2549
+ .form-ok {
2550
+ font-size: 13px;
2551
+ color: var(--accent-ink);
2552
+ min-height: 1.4em;
2553
+ }
2554
+
2555
+ /* ---------- 7. 归档 ---------- */
2556
+ .archive-head {
2557
+ max-width: 760px;
2558
+ margin-bottom: 32px;
2559
+ }
2560
+ .archive-head .page-title {
2561
+ font-family: var(--font-display);
2562
+ font-size: 30px;
2563
+ font-weight: 700;
2564
+ }
2565
+ .archive-head .page-sub {
2566
+ margin-top: 6px;
2567
+ color: var(--muted);
2568
+ font-size: 14.5px;
2569
+ }
2570
+ .timeline {
2571
+ max-width: 760px;
2572
+ margin: 0 auto;
2573
+ }
2574
+ .archive-year {
2575
+ display: flex;
2576
+ align-items: baseline;
2577
+ gap: 12px;
2578
+ margin: 28px 0 8px;
2579
+ scroll-margin-top: calc(var(--header-h) + 20px);
2580
+ }
2581
+ .archive-year .y {
2582
+ font-family: var(--font-display);
2583
+ font-size: 24px;
2584
+ font-weight: 700;
2585
+ }
2586
+ .archive-year .c {
2587
+ font-size: 13px;
2588
+ color: var(--muted);
2589
+ }
2590
+ .timeline-items {
2591
+ margin-left: 7px;
2592
+ border-left: 2px solid var(--border);
2593
+ padding-left: 26px;
2594
+ display: grid;
2595
+ gap: 6px;
2596
+ }
2597
+ .timeline-item {
2598
+ position: relative;
2599
+ padding: 10px 0;
2600
+ }
2601
+ .timeline-item::before {
2602
+ content: "";
2603
+ position: absolute;
2604
+ left: -33px;
2605
+ top: 22px;
2606
+ width: 8px;
2607
+ height: 8px;
2608
+ border-radius: 50%;
2609
+ background: var(--accent);
2610
+ box-shadow: 0 0 0 3px var(--accent-soft);
2611
+ }
2612
+ .timeline-item .t-date {
2613
+ font-size: 13px;
2614
+ color: var(--muted);
2615
+ font-variant-numeric: tabular-nums;
2616
+ }
2617
+ .timeline-item .t-title {
2618
+ display: inline-block;
2619
+ margin-left: 10px;
2620
+ font-weight: 600;
2621
+ color: var(--ink);
2622
+ }
2623
+ .timeline-item a:hover .t-title {
2624
+ color: var(--accent-deep);
2625
+ }
2626
+ html.dark .timeline-item a:hover .t-title {
2627
+ color: var(--accent);
2628
+ }
2629
+ .timeline-item .t-meta {
2630
+ margin-left: 10px;
2631
+ font-size: 12.5px;
2632
+ color: var(--muted);
2633
+ }
2634
+
2635
+ /* 归档按年折叠(§4.30):年份头为按钮时重置原生样式,fold 收起该年时间线 */
2636
+ button.archive-year {
2637
+ background: none;
2638
+ border: 0;
2639
+ padding: 0;
2640
+ font: inherit;
2641
+ color: inherit;
2642
+ cursor: pointer;
2643
+ text-align: left;
2644
+ }
2645
+ button.archive-year .year-caret {
2646
+ width: 16px;
2647
+ height: 16px;
2648
+ align-self: center;
2649
+ color: var(--muted);
2650
+ transition: transform 0.15s;
2651
+ }
2652
+ .timeline.fold button.archive-year .year-caret {
2653
+ transform: rotate(-90deg);
2654
+ }
2655
+ .timeline.fold .timeline-items {
2656
+ display: none;
2657
+ }
2658
+
2659
+ /* ---------- 7.1 专题(§4.31) ---------- */
2660
+ .series-grid {
2661
+ display: grid;
2662
+ grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
2663
+ gap: 16px;
2664
+ margin-bottom: 32px;
2665
+ }
2666
+ .series-card {
2667
+ display: block;
2668
+ padding: 20px 22px;
2669
+ }
2670
+ .series-card:hover {
2671
+ border-color: var(--accent-soft);
2672
+ }
2673
+ .series-name {
2674
+ margin: 0 0 8px;
2675
+ font-size: 17px;
2676
+ font-weight: 700;
2677
+ color: var(--ink);
2678
+ }
2679
+ .series-card:hover .series-name {
2680
+ color: var(--accent-deep);
2681
+ }
2682
+ .series-meta {
2683
+ margin: 0;
2684
+ display: flex;
2685
+ gap: 8px;
2686
+ font-size: 13px;
2687
+ color: var(--muted);
2688
+ }
2689
+ .series-empty {
2690
+ padding: 26px 30px;
2691
+ color: var(--muted);
2692
+ text-align: center;
2693
+ }
2694
+ .series-crumb a {
2695
+ color: var(--accent);
2696
+ }
2697
+ .series-crumb a:hover {
2698
+ text-decoration: underline;
2699
+ }
2700
+ .series-list {
2701
+ list-style: none;
2702
+ margin: 0 auto;
2703
+ padding: 0;
2704
+ max-width: 760px;
2705
+ display: grid;
2706
+ gap: 10px;
2707
+ }
2708
+ /* §4.75 专题分组:详情页组头(组内首条之前的小标题) */
2709
+ .series-group-title {
2710
+ margin-top: 16px;
2711
+ padding-left: 2px;
2712
+ font-size: 13px;
2713
+ font-weight: 700;
2714
+ letter-spacing: 0.04em;
2715
+ color: var(--muted);
2716
+ display: flex;
2717
+ align-items: center;
2718
+ gap: 8px;
2719
+ }
2720
+ .series-group-title::before {
2721
+ content: "";
2722
+ width: 14px;
2723
+ height: 3px;
2724
+ border-radius: 2px;
2725
+ background: var(--accent);
2726
+ }
2727
+ .series-group-title:first-child {
2728
+ margin-top: 0;
2729
+ }
2730
+ .series-link {
2731
+ display: flex;
2732
+ align-items: center;
2733
+ gap: 14px;
2734
+ padding: 14px 18px;
2735
+ }
2736
+ .series-idx {
2737
+ flex: none;
2738
+ width: 26px;
2739
+ height: 26px;
2740
+ display: inline-flex;
2741
+ align-items: center;
2742
+ justify-content: center;
2743
+ border-radius: 50%;
2744
+ background: var(--accent-soft);
2745
+ color: var(--accent-deep);
2746
+ font-size: 13px;
2747
+ font-weight: 700;
2748
+ font-variant-numeric: tabular-nums;
2749
+ }
2750
+ .series-title {
2751
+ flex: 1;
2752
+ min-width: 0;
2753
+ font-weight: 600;
2754
+ color: var(--ink);
2755
+ overflow: hidden;
2756
+ text-overflow: ellipsis;
2757
+ white-space: nowrap;
2758
+ }
2759
+ .series-link:hover .series-title {
2760
+ color: var(--accent-deep);
2761
+ }
2762
+ .series-date {
2763
+ flex: none;
2764
+ font-size: 13px;
2765
+ color: var(--muted);
2766
+ font-variant-numeric: tabular-nums;
2767
+ }
2768
+ /* 文章页专题导航卡(§4.31):目录超 6 项限高滚动 */
2769
+ .series-nav {
2770
+ margin: 0 0 28px;
2771
+ padding: 16px 20px;
2772
+ }
2773
+ .series-nav-head {
2774
+ display: flex;
2775
+ align-items: center;
2776
+ justify-content: space-between;
2777
+ gap: 12px;
2778
+ flex-wrap: wrap;
2779
+ margin-bottom: 10px;
2780
+ }
2781
+ .series-nav-title {
2782
+ display: inline-flex;
2783
+ align-items: center;
2784
+ gap: 8px;
2785
+ font-size: 15.5px;
2786
+ font-weight: 700;
2787
+ color: var(--ink);
2788
+ }
2789
+ .series-nav-title svg {
2790
+ width: 16px;
2791
+ height: 16px;
2792
+ color: var(--accent);
2793
+ }
2794
+ .series-nav-progress {
2795
+ display: inline-flex;
2796
+ align-items: center;
2797
+ gap: 10px;
2798
+ font-size: 13px;
2799
+ }
2800
+ .series-nav-progress a {
2801
+ color: var(--accent);
2802
+ }
2803
+ .series-nav-progress a:hover {
2804
+ text-decoration: underline;
2805
+ }
2806
+ .series-nav-count {
2807
+ color: var(--muted);
2808
+ font-variant-numeric: tabular-nums;
2809
+ }
2810
+ .series-nav-list {
2811
+ list-style: none;
2812
+ margin: 0;
2813
+ padding: 0;
2814
+ max-height: 280px;
2815
+ overflow-y: auto;
2816
+ display: grid;
2817
+ gap: 2px;
2818
+ }
2819
+ /* §4.75 专题分组:文章页专题目录组头 */
2820
+ .series-nav-group {
2821
+ margin-top: 8px;
2822
+ padding-left: 2px;
2823
+ font-size: 12px;
2824
+ font-weight: 700;
2825
+ letter-spacing: 0.04em;
2826
+ color: var(--muted);
2827
+ }
2828
+ .series-nav-group:first-child {
2829
+ margin-top: 0;
2830
+ }
2831
+ .series-nav-item {
2832
+ position: relative;
2833
+ padding-left: 14px;
2834
+ }
2835
+ .series-nav-item::before {
2836
+ content: "";
2837
+ position: absolute;
2838
+ left: 2px;
2839
+ top: 50%;
2840
+ transform: translateY(-50%);
2841
+ width: 5px;
2842
+ height: 5px;
2843
+ border-radius: 50%;
2844
+ background: var(--border);
2845
+ }
2846
+ .series-nav-item.cur::before {
2847
+ background: var(--accent);
2848
+ }
2849
+ .series-nav-row {
2850
+ display: flex;
2851
+ align-items: baseline;
2852
+ gap: 8px;
2853
+ padding: 4px 0;
2854
+ font-size: 14px;
2855
+ color: var(--ink-2);
2856
+ }
2857
+ a.series-nav-row:hover {
2858
+ color: var(--accent-deep);
2859
+ }
2860
+ .series-nav-idx {
2861
+ flex: none;
2862
+ min-width: 18px;
2863
+ text-align: right;
2864
+ color: var(--muted);
2865
+ font-size: 12.5px;
2866
+ font-variant-numeric: tabular-nums;
2867
+ }
2868
+ .series-nav-label {
2869
+ min-width: 0;
2870
+ overflow: hidden;
2871
+ text-overflow: ellipsis;
2872
+ white-space: nowrap;
2873
+ }
2874
+ .series-nav-item.cur .series-nav-row {
2875
+ font-weight: 600;
2876
+ color: var(--accent-deep);
2877
+ }
2878
+ html.dark .series-nav-item.cur .series-nav-row {
2879
+ color: var(--accent);
2880
+ }
2881
+ @media (max-width: 560px) {
2882
+ .series-date,
2883
+ .series-nav-count {
2884
+ display: none;
2885
+ }
2886
+ }
2887
+
2888
+ /* ---------- 8. 标签页 ---------- */
2889
+ .tag-cloud {
2890
+ display: flex;
2891
+ flex-wrap: wrap;
2892
+ gap: 14px 18px;
2893
+ align-items: baseline;
2894
+ padding: 26px 30px;
2895
+ margin-bottom: 32px;
2896
+ }
2897
+ .tag-s1 {
2898
+ font-size: 15px;
2899
+ color: var(--ink-2);
2900
+ }
2901
+ .tag-s3 {
2902
+ font-size: 24px;
2903
+ }
2904
+ .tag-cloud a {
2905
+ display: inline-block;
2906
+ line-height: 1.5;
2907
+ transition:
2908
+ color 0.15s,
2909
+ transform 0.15s;
2910
+ }
2911
+ .tag-cloud a:hover {
2912
+ transform: translateY(-2px);
2913
+ }
2914
+ .tag-cloud .tag-count {
2915
+ font-size: 0.7em;
2916
+ color: var(--muted);
2917
+ margin-left: 3px;
2918
+ vertical-align: super;
2919
+ }
2920
+ .tag-list-head {
2921
+ display: flex;
2922
+ align-items: center;
2923
+ justify-content: space-between;
2924
+ margin-bottom: 16px;
2925
+ }
2926
+ .tag-list {
2927
+ display: grid;
2928
+ gap: 14px;
2929
+ max-width: 760px;
2930
+ }
2931
+ .tag-empty {
2932
+ padding: 40px 0;
2933
+ text-align: center;
2934
+ color: var(--muted);
2935
+ }
2936
+
2937
+ /* ---------- 9. 画廊 / 友链(路由 M3b 接入) ---------- */
2938
+ .chips {
2939
+ display: flex;
2940
+ flex-wrap: wrap;
2941
+ gap: 10px;
2942
+ margin-bottom: 26px;
2943
+ }
2944
+ .gallery-grid {
2945
+ display: grid;
2946
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
2947
+ gap: 20px;
2948
+ }
2949
+ .album-card {
2950
+ overflow: hidden;
2951
+ cursor: pointer;
2952
+ transition:
2953
+ box-shadow 0.2s,
2954
+ transform 0.2s,
2955
+ border-color 0.2s;
2956
+ }
2957
+ .album-card:hover {
2958
+ box-shadow: var(--shadow-md);
2959
+ transform: translateY(-3px);
2960
+ border-color: var(--border-2);
2961
+ }
2962
+ .album-card.hidden {
2963
+ display: none;
2964
+ }
2965
+ .album-cover {
2966
+ position: relative;
2967
+ aspect-ratio: 1;
2968
+ overflow: hidden;
2969
+ }
2970
+ .album-cover img {
2971
+ width: 100%;
2972
+ height: 100%;
2973
+ object-fit: cover;
2974
+ transition: transform 0.5s ease;
2975
+ }
2976
+ .album-card:hover .album-cover img {
2977
+ transform: scale(1.04);
2978
+ }
2979
+ .album-cover .lock-badge {
2980
+ position: absolute;
2981
+ top: 12px;
2982
+ right: 12px;
2983
+ z-index: 2;
2984
+ display: inline-flex;
2985
+ align-items: center;
2986
+ gap: 5px;
2987
+ padding: 4px 12px;
2988
+ border-radius: 999px;
2989
+ font-size: 12px;
2990
+ background: rgba(0, 0, 0, 0.55);
2991
+ color: #fff;
2992
+ -webkit-backdrop-filter: blur(6px);
2993
+ backdrop-filter: blur(6px);
2994
+ }
2995
+ .album-cover .lock-badge svg {
2996
+ width: 13px;
2997
+ height: 13px;
2998
+ }
2999
+ .album-info {
3000
+ padding: 14px 18px 16px;
3001
+ display: flex;
3002
+ align-items: baseline;
3003
+ gap: 10px;
3004
+ }
3005
+ .album-name {
3006
+ font-weight: 600;
3007
+ font-family: var(--font-display);
3008
+ font-size: 16.5px;
3009
+ }
3010
+ .album-count {
3011
+ margin-left: auto;
3012
+ font-size: 13px;
3013
+ color: var(--muted);
3014
+ }
3015
+ .album-tags {
3016
+ padding: 0 18px 16px;
3017
+ margin-top: -6px;
3018
+ display: flex;
3019
+ gap: 6px;
3020
+ }
3021
+ .album-tags .chip {
3022
+ font-size: 12px;
3023
+ padding: 1px 10px;
3024
+ }
3025
+ .album-sub {
3026
+ padding: 0 18px;
3027
+ margin-top: -8px;
3028
+ display: flex;
3029
+ flex-wrap: wrap;
3030
+ gap: 12px;
3031
+ font-size: 12.5px;
3032
+ color: var(--muted);
3033
+ }
3034
+ .album-cover-fallback {
3035
+ width: 100%;
3036
+ height: 100%;
3037
+ display: flex;
3038
+ align-items: center;
3039
+ justify-content: center;
3040
+ color: var(--muted);
3041
+ background: var(--bg-soft);
3042
+ }
3043
+ .album-cover-fallback svg {
3044
+ width: 34px;
3045
+ height: 34px;
3046
+ opacity: 0.55;
3047
+ }
3048
+
3049
+ /* 相册列表搜索(M3b-b8):与 modal input 同一套视觉 */
3050
+ .gallery-search {
3051
+ position: relative;
3052
+ margin-bottom: 16px;
3053
+ }
3054
+ .gallery-search svg {
3055
+ position: absolute;
3056
+ left: 13px;
3057
+ top: 50%;
3058
+ transform: translateY(-50%);
3059
+ width: 16px;
3060
+ height: 16px;
3061
+ color: var(--muted);
3062
+ pointer-events: none;
3063
+ }
3064
+ .gallery-search input {
3065
+ width: 100%;
3066
+ padding: 10px 14px 10px 38px;
3067
+ border-radius: var(--radius-sm);
3068
+ border: 1px solid var(--border-2);
3069
+ background: var(--bg);
3070
+ color: var(--ink);
3071
+ font-size: 14px;
3072
+ transition:
3073
+ border-color 0.15s,
3074
+ box-shadow 0.15s;
3075
+ }
3076
+ .gallery-search input:focus {
3077
+ outline: none;
3078
+ border-color: var(--accent);
3079
+ box-shadow: 0 0 0 3px var(--accent-soft);
3080
+ }
3081
+ .gallery-empty {
3082
+ padding: 48px 0;
3083
+ text-align: center;
3084
+ color: var(--muted);
3085
+ }
3086
+
3087
+ /* 相册详情页(M3b-b8):封面横幅 + 瀑布流 */
3088
+ .gallery-banner {
3089
+ position: relative;
3090
+ overflow: hidden;
3091
+ border-radius: var(--radius);
3092
+ aspect-ratio: 3 / 1;
3093
+ min-height: 200px;
3094
+ max-height: 360px;
3095
+ background: var(--bg-soft);
3096
+ }
3097
+ .gallery-banner > img {
3098
+ width: 100%;
3099
+ height: 100%;
3100
+ object-fit: cover;
3101
+ }
3102
+ .gallery-banner::after {
3103
+ content: "";
3104
+ position: absolute;
3105
+ inset: 0;
3106
+ background: linear-gradient(
3107
+ to top,
3108
+ rgba(0, 0, 0, 0.72),
3109
+ rgba(0, 0, 0, 0.28) 45%,
3110
+ rgba(0, 0, 0, 0.05)
3111
+ );
3112
+ }
3113
+ .gallery-back {
3114
+ position: absolute;
3115
+ top: 16px;
3116
+ left: 16px;
3117
+ z-index: 2;
3118
+ display: inline-flex;
3119
+ align-items: center;
3120
+ gap: 6px;
3121
+ padding: 6px 14px;
3122
+ border-radius: 999px;
3123
+ font-size: 13px;
3124
+ color: rgba(255, 255, 255, 0.92);
3125
+ background: rgba(0, 0, 0, 0.32);
3126
+ -webkit-backdrop-filter: blur(6px);
3127
+ backdrop-filter: blur(6px);
3128
+ transition: background-color 0.15s;
3129
+ }
3130
+ .gallery-back:hover {
3131
+ background: rgba(0, 0, 0, 0.52);
3132
+ color: #fff;
3133
+ }
3134
+ .gallery-back svg {
3135
+ width: 14px;
3136
+ height: 14px;
3137
+ }
3138
+ .gallery-banner-inner {
3139
+ position: absolute;
3140
+ left: 0;
3141
+ right: 0;
3142
+ bottom: 0;
3143
+ z-index: 1;
3144
+ padding: 22px 26px;
3145
+ color: #fff;
3146
+ }
3147
+ .gallery-title {
3148
+ font-family: var(--font-display);
3149
+ font-size: 24px;
3150
+ font-weight: 700;
3151
+ }
3152
+ .gallery-desc {
3153
+ margin-top: 6px;
3154
+ max-width: 640px;
3155
+ font-size: 14px;
3156
+ color: rgba(255, 255, 255, 0.78);
3157
+ }
3158
+ .gallery-meta {
3159
+ margin-top: 10px;
3160
+ display: flex;
3161
+ flex-wrap: wrap;
3162
+ align-items: center;
3163
+ gap: 16px;
3164
+ font-size: 13px;
3165
+ color: rgba(255, 255, 255, 0.82);
3166
+ }
3167
+ .gallery-meta svg {
3168
+ width: 14px;
3169
+ height: 14px;
3170
+ vertical-align: -2px;
3171
+ margin-right: 3px;
3172
+ }
3173
+ .gallery-meta .gallery-meta-tags {
3174
+ display: inline-flex;
3175
+ flex-wrap: wrap;
3176
+ gap: 6px;
3177
+ }
3178
+ .gallery-meta .gallery-meta-tags span {
3179
+ padding: 1px 10px;
3180
+ border-radius: 999px;
3181
+ font-size: 12px;
3182
+ background: rgba(255, 255, 255, 0.2);
3183
+ -webkit-backdrop-filter: blur(6px);
3184
+ backdrop-filter: blur(6px);
3185
+ }
3186
+ /* 无封面降级:卡式头部 */
3187
+ .gallery-head-plain {
3188
+ padding: 20px 24px;
3189
+ }
3190
+ .gallery-head-plain .gallery-title {
3191
+ color: var(--ink);
3192
+ }
3193
+ /* 降级头部 meta 位于浅色卡面:覆盖横幅白色系配色 */
3194
+ .gallery-head-plain .gallery-meta {
3195
+ color: var(--muted);
3196
+ }
3197
+ .gallery-head-plain .gallery-meta .gallery-meta-tags span {
3198
+ background: var(--bg-soft);
3199
+ color: var(--ink-2);
3200
+ -webkit-backdrop-filter: none;
3201
+ backdrop-filter: none;
3202
+ }
3203
+ /* 筛选容器 custom element:默认 inline,恢复块级 */
3204
+ gallery-filter {
3205
+ display: block;
3206
+ }
3207
+
3208
+ .gallery-masonry {
3209
+ column-count: 2;
3210
+ column-gap: 12px;
3211
+ }
3212
+ @media (min-width: 640px) {
3213
+ .gallery-masonry {
3214
+ column-width: var(--col-width, 240px);
3215
+ column-count: auto;
3216
+ }
3217
+ }
3218
+ .gallery-photo {
3219
+ position: relative;
3220
+ break-inside: avoid;
3221
+ margin: 0 0 12px;
3222
+ overflow: hidden;
3223
+ border-radius: var(--radius-sm);
3224
+ background: var(--bg-soft);
3225
+ cursor: zoom-in;
3226
+ }
3227
+ .gallery-photo img {
3228
+ display: block;
3229
+ width: 100%;
3230
+ height: auto;
3231
+ transition: transform 0.35s ease;
3232
+ }
3233
+ .gallery-photo:hover img {
3234
+ transform: scale(1.025);
3235
+ }
3236
+
3237
+ /* 灯箱(§4.69):样式由 photoswipe/photoswipe.css 提供(BaseLayout 引入) */
3238
+ /* 灯箱自定义 UI(§4.70/§4.71):全屏/自动播放按钮与缩略图条(可开关、内容居中)。
3239
+ 自定义图标用 .qy-pswp-icn 独立类名,避开 .pswp__icn 的 fill 覆盖(图标走 stroke 描边) */
3240
+ .qy-pswp-icn {
3241
+ position: absolute;
3242
+ inset: 0;
3243
+ margin: auto;
3244
+ width: 24px;
3245
+ height: 24px;
3246
+ stroke: var(--pswp-icon-color, #fff);
3247
+ fill: none;
3248
+ stroke-width: 1.6;
3249
+ stroke-linecap: round;
3250
+ stroke-linejoin: round;
3251
+ pointer-events: none;
3252
+ }
3253
+ .qy-icn-fill {
3254
+ fill: var(--pswp-icon-color, #fff);
3255
+ stroke: none;
3256
+ }
3257
+ .pswp__button--qy-fullscreen .qy-icn-fs-exit,
3258
+ .pswp__button--qy-slideshow .qy-icn-pause {
3259
+ display: none;
3260
+ }
3261
+ .pswp__button--qy-slideshow.is-active .qy-icn-play {
3262
+ display: none;
3263
+ }
3264
+ .pswp__button--qy-slideshow.is-active .qy-icn-pause {
3265
+ display: block;
3266
+ }
3267
+ .pswp:fullscreen .pswp__button--qy-fullscreen .qy-icn-fs-enter,
3268
+ .pswp:-webkit-full-screen .pswp__button--qy-fullscreen .qy-icn-fs-enter {
3269
+ display: none;
3270
+ }
3271
+ .pswp:fullscreen .pswp__button--qy-fullscreen .qy-icn-fs-exit,
3272
+ .pswp:-webkit-full-screen .pswp__button--qy-fullscreen .qy-icn-fs-exit {
3273
+ display: block;
3274
+ }
3275
+ .pswp__qy-thumbs {
3276
+ position: absolute;
3277
+ left: 0;
3278
+ right: 0;
3279
+ bottom: 0;
3280
+ z-index: 10;
3281
+ display: flex;
3282
+ gap: 8px;
3283
+ padding: 10px 12px;
3284
+ overflow-x: auto;
3285
+ background: linear-gradient(transparent, rgba(0, 0, 0, 0.4));
3286
+ -webkit-overflow-scrolling: touch;
3287
+ scrollbar-width: none;
3288
+ }
3289
+ .pswp__qy-thumbs::-webkit-scrollbar {
3290
+ display: none;
3291
+ }
3292
+ .pswp__qy-thumb {
3293
+ flex: 0 0 auto;
3294
+ width: 64px;
3295
+ height: 40px;
3296
+ padding: 0;
3297
+ border: 1px solid transparent;
3298
+ border-radius: 4px;
3299
+ overflow: hidden;
3300
+ opacity: 0.5;
3301
+ background: none;
3302
+ cursor: pointer;
3303
+ }
3304
+ .pswp__qy-thumb img {
3305
+ display: block;
3306
+ width: 100%;
3307
+ height: 100%;
3308
+ object-fit: cover;
3309
+ }
3310
+ .pswp__qy-thumb:hover {
3311
+ opacity: 0.85;
3312
+ }
3313
+ .pswp__qy-thumb.is-active {
3314
+ opacity: 1;
3315
+ border-color: var(--pswp-icon-color, #fff);
3316
+ }
3317
+ /* §4.71:缩略图条内容居中——首尾缩略图 margin auto 撑开空隙;图多溢出时 auto 归零,
3318
+ 自然退化为左对齐横向滚动,不会裁切左侧(flex 对齐安全技巧) */
3319
+ .pswp__qy-thumbs > .pswp__qy-thumb:first-child {
3320
+ margin-left: auto;
3321
+ }
3322
+ .pswp__qy-thumbs > .pswp__qy-thumb:last-child {
3323
+ margin-right: auto;
3324
+ }
3325
+ /* §4.71:开关按钮收起缩略图条 */
3326
+ .pswp__qy-thumbs.is-hidden {
3327
+ display: none;
3328
+ }
3329
+ @media (max-width: 639px) {
3330
+ .pswp__qy-thumbs {
3331
+ display: none;
3332
+ }
3333
+ }
3334
+
3335
+ /* modal(加密相册,M3b) */
3336
+ .modal {
3337
+ position: fixed;
3338
+ inset: 0;
3339
+ z-index: 320;
3340
+ display: flex;
3341
+ align-items: center;
3342
+ justify-content: center;
3343
+ background: rgba(12, 14, 15, 0.55);
3344
+ -webkit-backdrop-filter: blur(4px);
3345
+ backdrop-filter: blur(4px);
3346
+ opacity: 0;
3347
+ pointer-events: none;
3348
+ transition: opacity 0.2s;
3349
+ }
3350
+ .modal.open {
3351
+ opacity: 1;
3352
+ pointer-events: auto;
3353
+ }
3354
+ .modal-box {
3355
+ width: min(360px, calc(100vw - 48px));
3356
+ padding: 26px 26px 22px;
3357
+ background: var(--surface);
3358
+ border: 1px solid var(--border);
3359
+ border-radius: var(--radius);
3360
+ box-shadow: var(--shadow-md);
3361
+ }
3362
+ .modal-box h3 {
3363
+ font-family: var(--font-display);
3364
+ font-size: 18px;
3365
+ margin-bottom: 6px;
3366
+ }
3367
+ .modal-box .modal-hint {
3368
+ font-size: 13.5px;
3369
+ color: var(--muted);
3370
+ margin-bottom: 16px;
3371
+ }
3372
+ .modal-box input {
3373
+ width: 100%;
3374
+ padding: 10px 14px;
3375
+ border-radius: var(--radius-sm);
3376
+ border: 1px solid var(--border-2);
3377
+ background: var(--bg);
3378
+ color: var(--ink);
3379
+ }
3380
+ .modal-box input:focus {
3381
+ outline: none;
3382
+ border-color: var(--accent);
3383
+ box-shadow: 0 0 0 3px var(--accent-soft);
3384
+ }
3385
+ .modal-actions {
3386
+ margin-top: 16px;
3387
+ display: flex;
3388
+ justify-content: flex-end;
3389
+ gap: 10px;
3390
+ }
3391
+ .modal-error {
3392
+ margin-top: 10px;
3393
+ font-size: 13px;
3394
+ color: #c0564f;
3395
+ min-height: 1.3em;
3396
+ }
3397
+ .modal-box.shake {
3398
+ animation: shake 0.4s;
3399
+ }
3400
+ @keyframes shake {
3401
+ 0%,
3402
+ 100% {
3403
+ transform: translateX(0);
3404
+ }
3405
+ 25% {
3406
+ transform: translateX(-7px);
3407
+ }
3408
+ 50% {
3409
+ transform: translateX(6px);
3410
+ }
3411
+ 75% {
3412
+ transform: translateX(-4px);
3413
+ }
3414
+ }
3415
+
3416
+ /* ---------- 10. 友链 ---------- */
3417
+ .friend-grid {
3418
+ display: grid;
3419
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
3420
+ gap: 20px;
3421
+ }
3422
+ .friend-card {
3423
+ display: flex;
3424
+ gap: 16px;
3425
+ align-items: center;
3426
+ padding: 20px 22px;
3427
+ color: var(--ink);
3428
+ transition:
3429
+ box-shadow 0.2s,
3430
+ transform 0.2s,
3431
+ border-color 0.2s;
3432
+ }
3433
+ .friend-card:hover {
3434
+ box-shadow: var(--shadow-md);
3435
+ transform: translateY(-2px);
3436
+ border-color: var(--border-2);
3437
+ color: var(--ink);
3438
+ }
3439
+ .friend-avatar {
3440
+ flex: none;
3441
+ width: 56px;
3442
+ height: 56px;
3443
+ border-radius: 50%;
3444
+ overflow: hidden;
3445
+ border: 1px solid var(--border);
3446
+ }
3447
+ .friend-avatar img {
3448
+ width: 100%;
3449
+ height: 100%;
3450
+ object-fit: cover;
3451
+ }
3452
+ .friend-name {
3453
+ font-weight: 700;
3454
+ font-size: 16px;
3455
+ font-family: var(--font-display);
3456
+ }
3457
+ .friend-card:hover .friend-name {
3458
+ color: var(--accent-deep);
3459
+ }
3460
+ html.dark .friend-card:hover .friend-name {
3461
+ color: var(--accent);
3462
+ }
3463
+ .friend-desc {
3464
+ margin-top: 3px;
3465
+ font-size: 13.5px;
3466
+ color: var(--muted);
3467
+ line-height: 1.6;
3468
+ }
3469
+ .friend-apply {
3470
+ margin-top: 20px;
3471
+ padding: 24px 26px;
3472
+ display: flex;
3473
+ align-items: center;
3474
+ justify-content: space-between;
3475
+ gap: 18px;
3476
+ flex-wrap: wrap;
3477
+ }
3478
+ .friend-apply .fa-title {
3479
+ font-family: var(--font-display);
3480
+ font-weight: 700;
3481
+ font-size: 17px;
3482
+ }
3483
+ .friend-apply .fa-desc {
3484
+ margin-top: 4px;
3485
+ font-size: 14px;
3486
+ color: var(--muted);
3487
+ }
3488
+ .friend-tags {
3489
+ margin-top: 7px;
3490
+ display: flex;
3491
+ flex-wrap: wrap;
3492
+ gap: 4px;
3493
+ }
3494
+ .friend-tags .chip {
3495
+ font-size: 11px;
3496
+ padding: 1px 9px;
3497
+ }
3498
+
3499
+ /* ---------- 10.1 字头像兜底(友链/打赏名单无图时) ---------- */
3500
+ .avatar-fallback {
3501
+ display: inline-flex;
3502
+ align-items: center;
3503
+ justify-content: center;
3504
+ background: var(--accent-soft);
3505
+ color: var(--accent-ink);
3506
+ font-weight: 700;
3507
+ user-select: none;
3508
+ }
3509
+ .friend-avatar .avatar-fallback {
3510
+ width: 100%;
3511
+ height: 100%;
3512
+ font-size: 20px;
3513
+ font-family: var(--font-display);
3514
+ }
3515
+ .side-friends .avatar-fallback {
3516
+ width: 24px;
3517
+ height: 24px;
3518
+ font-size: 12px;
3519
+ border-radius: 50%;
3520
+ border: 1px solid var(--border);
3521
+ flex: none;
3522
+ }
3523
+ .sponsor-item-avatar.avatar-fallback {
3524
+ border-radius: 50%;
3525
+ font-size: 14px;
3526
+ }
3527
+
3528
+ /* ---------- 10.2 独立页(关于/留言板)正文卡 ---------- */
3529
+ .page-card {
3530
+ margin-top: 26px;
3531
+ padding: 26px 30px;
3532
+ }
3533
+ .page-card .prose > :first-child,
3534
+ .prose.page-card > :first-child {
3535
+ margin-top: 0;
3536
+ }
3537
+ .comment-placeholder {
3538
+ text-align: center;
3539
+ color: var(--muted);
3540
+ font-size: 14px;
3541
+ }
3542
+ .comment-placeholder p {
3543
+ margin: 8px 0;
3544
+ }
3545
+
3546
+ /* ---------- 10.3 打赏页 ---------- */
3547
+ .sponsor-usage {
3548
+ margin-top: 26px;
3549
+ padding: 14px 18px;
3550
+ font-size: 14px;
3551
+ color: var(--ink-2);
3552
+ line-height: 1.7;
3553
+ background: var(--accent-soft);
3554
+ border: 1px solid hsl(var(--accent-h) 30% 60% / 0.45);
3555
+ }
3556
+ .sponsor-grid {
3557
+ margin-top: 26px;
3558
+ display: grid;
3559
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
3560
+ gap: 20px;
3561
+ }
3562
+ .sponsor-method {
3563
+ display: flex;
3564
+ flex-direction: column;
3565
+ align-items: center;
3566
+ gap: 12px;
3567
+ padding: 26px 22px;
3568
+ text-align: center;
3569
+ }
3570
+ .sponsor-method .sm-name {
3571
+ font-family: var(--font-display);
3572
+ font-weight: 700;
3573
+ font-size: 17px;
3574
+ display: flex;
3575
+ align-items: center;
3576
+ gap: 8px;
3577
+ }
3578
+ .sponsor-method .sm-icon {
3579
+ font-size: 20px;
3580
+ }
3581
+ .sponsor-method .sm-desc {
3582
+ margin: 0;
3583
+ font-size: 13.5px;
3584
+ color: var(--muted);
3585
+ }
3586
+ .sponsor-qr {
3587
+ width: 180px;
3588
+ height: 180px;
3589
+ padding: 12px;
3590
+ background: #fff;
3591
+ border: 1px solid var(--border);
3592
+ border-radius: 12px;
3593
+ object-fit: contain;
3594
+ }
3595
+ .sponsor-qr-empty {
3596
+ display: flex;
3597
+ align-items: center;
3598
+ justify-content: center;
3599
+ color: var(--muted);
3600
+ font-size: 13px;
3601
+ }
3602
+ .sponsor-method .sm-link {
3603
+ margin-top: auto;
3604
+ }
3605
+ .sponsor-list-title {
3606
+ font-family: var(--font-display);
3607
+ font-size: 17px;
3608
+ font-weight: 700;
3609
+ margin: 0 0 14px;
3610
+ }
3611
+ .sponsor-list-title .sl-count {
3612
+ margin-left: 8px;
3613
+ font-size: 12px;
3614
+ color: var(--muted);
3615
+ font-variant-numeric: tabular-nums;
3616
+ font-weight: 400;
3617
+ }
3618
+ .sponsor-list {
3619
+ display: grid;
3620
+ gap: 10px;
3621
+ }
3622
+ .sponsor-item {
3623
+ display: flex;
3624
+ align-items: center;
3625
+ gap: 12px;
3626
+ padding: 10px 14px;
3627
+ border: 1px solid var(--border);
3628
+ border-radius: 14px;
3629
+ }
3630
+ .sponsor-item-avatar {
3631
+ flex: none;
3632
+ width: 36px;
3633
+ height: 36px;
3634
+ border-radius: 50%;
3635
+ object-fit: cover;
3636
+ border: 1px solid var(--border);
3637
+ }
3638
+ .sponsor-item-name {
3639
+ font-size: 14px;
3640
+ font-weight: 600;
3641
+ display: flex;
3642
+ align-items: baseline;
3643
+ gap: 8px;
3644
+ flex-wrap: wrap;
3645
+ }
3646
+ .sponsor-item-name .sl-amount {
3647
+ color: var(--accent-ink);
3648
+ font-size: 13px;
3649
+ }
3650
+ .sponsor-item-date {
3651
+ font-size: 12.5px;
3652
+ color: var(--muted);
3653
+ }
3654
+
3655
+ /* ---------- 11. Footer ---------- */
3656
+ .site-footer {
3657
+ border-top: 1px solid var(--border);
3658
+ background: var(--bg-soft);
3659
+ }
3660
+ .footer-inner {
3661
+ padding: 36px 24px 40px;
3662
+ text-align: center;
3663
+ }
3664
+ /* §4.57 行距统一收口:任意行(含自定义行)相邻间距恒定,customHtml 缺省时无多余上边距 */
3665
+ .footer-inner > * + * {
3666
+ margin-top: 6px;
3667
+ }
3668
+ .footer-line {
3669
+ font-size: 14px;
3670
+ color: var(--ink-2);
3671
+ }
3672
+ /* §4.57 页脚链接(RSS/Sitemap/Powered by/自定义行)统一 accent 风格,hover 才出下划线 */
3673
+ .footer-line a,
3674
+ .footer-sub a,
3675
+ .footer-custom a {
3676
+ color: var(--accent);
3677
+ text-decoration: none;
3678
+ }
3679
+ .footer-line a:hover,
3680
+ .footer-sub a:hover,
3681
+ .footer-custom a:hover {
3682
+ text-decoration: underline;
3683
+ text-underline-offset: 2px;
3684
+ }
3685
+ .footer-sep {
3686
+ margin: 0 6px;
3687
+ color: var(--muted);
3688
+ }
3689
+ .footer-sub {
3690
+ font-size: 12.5px;
3691
+ color: var(--muted);
3692
+ }
3693
+ /* §4.57 自定义行(备案号/统计等多段内容):flex 换行居中,与相邻行同字号同色 */
3694
+ .footer-custom {
3695
+ display: flex;
3696
+ flex-wrap: wrap;
3697
+ justify-content: center;
3698
+ gap: 2px 16px;
3699
+ font-size: 12.5px;
3700
+ color: var(--muted);
3701
+ }
3702
+
3703
+ /* ---------- 12. 搜索浮层(M3b Pagefind 启用) ---------- */
3704
+ .search-overlay {
3705
+ position: fixed;
3706
+ inset: 0;
3707
+ z-index: 250;
3708
+ background: rgba(12, 14, 15, 0.45);
3709
+ -webkit-backdrop-filter: blur(6px);
3710
+ backdrop-filter: blur(6px);
3711
+ display: flex;
3712
+ justify-content: center;
3713
+ align-items: flex-start;
3714
+ padding: 12vh 20px 0;
3715
+ }
3716
+ .search-overlay[hidden] {
3717
+ display: none !important;
3718
+ }
3719
+ .search-panel {
3720
+ width: min(560px, 100%);
3721
+ background: var(--surface);
3722
+ border: 1px solid var(--border);
3723
+ border-radius: var(--radius);
3724
+ box-shadow: var(--shadow-md);
3725
+ overflow: hidden;
3726
+ }
3727
+ .search-box {
3728
+ display: flex;
3729
+ align-items: center;
3730
+ gap: 10px;
3731
+ padding: 14px 16px;
3732
+ border-bottom: 1px solid var(--border);
3733
+ }
3734
+ .search-box > svg {
3735
+ flex: none;
3736
+ width: 18px;
3737
+ height: 18px;
3738
+ color: var(--muted);
3739
+ }
3740
+ .search-box input {
3741
+ flex: 1;
3742
+ border: none;
3743
+ background: transparent;
3744
+ outline: none;
3745
+ font-size: 16px;
3746
+ color: var(--ink);
3747
+ }
3748
+ .search-box input::placeholder {
3749
+ color: var(--muted);
3750
+ }
3751
+ .search-results {
3752
+ max-height: 320px;
3753
+ overflow-y: auto;
3754
+ padding: 8px;
3755
+ }
3756
+ .search-item {
3757
+ display: block;
3758
+ width: 100%;
3759
+ text-align: left;
3760
+ padding: 10px 14px;
3761
+ border-radius: var(--radius-sm);
3762
+ }
3763
+ .search-item .si-title {
3764
+ font-size: 14.5px;
3765
+ font-weight: 600;
3766
+ color: var(--ink);
3767
+ }
3768
+ .search-item .si-meta {
3769
+ margin-top: 2px;
3770
+ font-size: 12.5px;
3771
+ color: var(--muted);
3772
+ }
3773
+ .search-item.is-active,
3774
+ .search-item:hover {
3775
+ background: var(--accent-soft);
3776
+ }
3777
+ .search-item.is-active .si-title {
3778
+ color: var(--accent-ink);
3779
+ }
3780
+ .search-empty {
3781
+ padding: 34px 0;
3782
+ text-align: center;
3783
+ color: var(--muted);
3784
+ font-size: 14px;
3785
+ }
3786
+ .search-hint {
3787
+ padding: 10px 16px;
3788
+ font-size: 12px;
3789
+ color: var(--muted);
3790
+ border-top: 1px solid var(--border);
3791
+ background: var(--bg-soft);
3792
+ }
3793
+
3794
+ /* ---------- 13. back-top ---------- */
3795
+ /* 阅读进度条(§4.12):fixed 顶边 3px,scaleX 驱动零重排;层级盖过 header(100)、让位 skip-link(200) */
3796
+ .read-progress {
3797
+ position: fixed;
3798
+ top: 0;
3799
+ left: 0;
3800
+ z-index: 150;
3801
+ width: 100%;
3802
+ height: 3px;
3803
+ transform-origin: 0 50%;
3804
+ transform: scaleX(0);
3805
+ background: linear-gradient(
3806
+ 90deg,
3807
+ var(--accent),
3808
+ var(--accent-deep, var(--accent))
3809
+ );
3810
+ pointer-events: none;
3811
+ }
3812
+ .back-top {
3813
+ position: fixed;
3814
+ right: 26px;
3815
+ bottom: 30px;
3816
+ z-index: 90;
3817
+ width: 42px;
3818
+ height: 42px;
3819
+ border-radius: 50%;
3820
+ display: flex;
3821
+ align-items: center;
3822
+ justify-content: center;
3823
+ background: var(--surface);
3824
+ color: var(--ink-2);
3825
+ border: 1px solid var(--border);
3826
+ box-shadow: var(--shadow-sm);
3827
+ transition:
3828
+ color 0.15s,
3829
+ border-color 0.15s,
3830
+ transform 0.15s;
3831
+ }
3832
+ .back-top:hover {
3833
+ color: var(--accent-ink);
3834
+ border-color: var(--accent);
3835
+ transform: translateY(-2px);
3836
+ }
3837
+ .back-top svg {
3838
+ width: 20px;
3839
+ height: 20px;
3840
+ }
3841
+
3842
+ /* ---------- 14. 响应式 ---------- */
3843
+ @media (max-width: 860px) {
3844
+ .site-nav {
3845
+ position: absolute;
3846
+ top: var(--header-h);
3847
+ left: 0;
3848
+ right: 0;
3849
+ flex-direction: column;
3850
+ align-items: stretch;
3851
+ gap: 2px;
3852
+ margin: 0;
3853
+ padding: 10px 16px 14px;
3854
+ background: var(--surface);
3855
+ border-bottom: 1px solid var(--border);
3856
+ box-shadow: var(--shadow-md);
3857
+ display: none;
3858
+ }
3859
+ .site-nav.open {
3860
+ display: flex;
3861
+ }
3862
+ .nav-link {
3863
+ padding: 10px 14px;
3864
+ border-radius: var(--radius-sm);
3865
+ }
3866
+ .nav-burger {
3867
+ display: inline-flex;
3868
+ }
3869
+ }
3870
+ @media (max-width: 640px) {
3871
+ /* 小屏留白收紧(§4.13):24px 留白在窄屏占比过大 */
3872
+ .shell {
3873
+ padding-inline: 16px;
3874
+ }
3875
+ .post-body {
3876
+ padding: 18px 18px 20px;
3877
+ }
3878
+ .post-card.no-cover:not(.compact) .post-body {
3879
+ padding-right: 72px;
3880
+ }
3881
+ .side-card {
3882
+ /* §4.46 移动端与桌面统一 16px 内边距 */
3883
+ padding: 16px;
3884
+ }
3885
+ .site-main {
3886
+ padding-top: 24px;
3887
+ }
3888
+ .hero {
3889
+ padding: 12px 0 28px;
3890
+ }
3891
+ .post-card.featured {
3892
+ grid-template-columns: 1fr;
3893
+ }
3894
+ .post-card.featured .post-cover {
3895
+ aspect-ratio: 16 / 9;
3896
+ min-height: 0;
3897
+ }
3898
+ .post-card.compact {
3899
+ grid-template-columns: 96px 1fr;
3900
+ }
3901
+ .post-nav {
3902
+ grid-template-columns: 1fr;
3903
+ }
3904
+ .post-nav .next {
3905
+ text-align: left;
3906
+ }
3907
+ .home-layout {
3908
+ gap: 24px;
3909
+ }
3910
+ .back-top {
3911
+ right: 16px;
3912
+ bottom: 20px;
3913
+ }
3914
+ /* 搜索移动端形态(§4.56):内联框退化为 icon 按钮,浮层内含输入框 */
3915
+ .nav-search {
3916
+ display: none;
3917
+ }
3918
+ .nav-search-toggle {
3919
+ display: inline-flex;
3920
+ }
3921
+ .search-bar {
3922
+ display: flex;
3923
+ }
3924
+ /* 搜索浮层移动端:fixed 贴边铺开 */
3925
+ .search-pop {
3926
+ position: fixed;
3927
+ left: 12px;
3928
+ right: 12px;
3929
+ top: calc(var(--header-h) + 8px);
3930
+ width: auto;
3931
+ }
3932
+ }
3933
+
3934
+ /* ---------- 15. 动效偏好 ---------- */
3935
+ @media (prefers-reduced-motion: reduce) {
3936
+ html {
3937
+ scroll-behavior: auto;
3938
+ }
3939
+ *,
3940
+ *::before,
3941
+ *::after {
3942
+ animation-duration: 0.01ms !important;
3943
+ transition-duration: 0.01ms !important;
3944
+ }
3945
+ .reveal {
3946
+ opacity: 1;
3947
+ transform: none;
3948
+ }
3949
+ }
3950
+
3951
+ /* ---------- 16. 图表与公式 / 邮箱防爬(M3b-b4) ---------- */
3952
+ .diagram-container {
3953
+ position: relative;
3954
+ margin: 24px 0;
3955
+ padding: 4px;
3956
+ overflow: hidden;
3957
+ border: 1px solid var(--border);
3958
+ border-radius: var(--radius);
3959
+ background: var(--surface);
3960
+ /* 触摸设备:垂直滚动留给页面,捏合交给全屏层 */
3961
+ touch-action: pan-y;
3962
+ }
3963
+ .diagram-wrapper {
3964
+ text-align: center;
3965
+ }
3966
+ .mermaid-svg-light svg,
3967
+ .mermaid-svg-dark svg,
3968
+ .plantuml-image {
3969
+ max-width: 100%;
3970
+ height: auto;
3971
+ margin: 0 auto;
3972
+ }
3973
+ /* Mermaid 构建期双主题:同一份图渲染两份 SVG,按暗色模式显隐 */
3974
+ .mermaid-svg-dark {
3975
+ display: none;
3976
+ }
3977
+ html.dark .mermaid-svg-light {
3978
+ display: none;
3979
+ }
3980
+ html.dark .mermaid-svg-dark {
3981
+ display: block;
3982
+ }
3983
+
3984
+ /* Mermaid 渲染失败降级:提示 + 源码 */
3985
+ .mermaid-error {
3986
+ padding: 14px 16px;
3987
+ text-align: left;
3988
+ }
3989
+ .mermaid-error p,
3990
+ .plantuml-error p {
3991
+ font-size: 0.9em;
3992
+ color: var(--muted);
3993
+ }
3994
+ .mermaid-error .mermaid-fallback-code {
3995
+ margin: 10px 0 0;
3996
+ padding: 14px;
3997
+ font-family: var(--font-mono);
3998
+ font-size: 0.85em;
3999
+ line-height: 1.6;
4000
+ overflow-x: auto;
4001
+ white-space: pre-wrap;
4002
+ word-break: break-word;
4003
+ background: var(--bg-soft);
4004
+ border-radius: var(--radius-sm);
4005
+ }
4006
+
4007
+ /* PlantUML 加载失败:提示 + 重试 */
4008
+ .plantuml-error {
4009
+ padding: 2px 0 10px;
4010
+ text-align: center;
4011
+ }
4012
+ .plantuml-error button {
4013
+ margin-top: 8px;
4014
+ padding: 4px 14px;
4015
+ border: 1px solid var(--border-2);
4016
+ border-radius: var(--radius-sm);
4017
+ background: var(--surface);
4018
+ color: var(--ink-2);
4019
+ font-size: 0.85em;
4020
+ cursor: pointer;
4021
+ }
4022
+ .plantuml-error button:hover {
4023
+ color: var(--ink);
4024
+ border-color: var(--muted);
4025
+ }
4026
+
4027
+ /* pan-zoom 控制栏:悬停浮出,触屏常显 */
4028
+ .diagram-controls {
4029
+ position: absolute;
4030
+ top: 8px;
4031
+ right: 8px;
4032
+ z-index: 2;
4033
+ display: flex;
4034
+ gap: 2px;
4035
+ padding: 3px;
4036
+ background: hsl(0 0% 100% / 0.85);
4037
+ backdrop-filter: blur(4px);
4038
+ border: 1px solid var(--border);
4039
+ border-radius: var(--radius-sm);
4040
+ box-shadow: var(--shadow-sm);
4041
+ opacity: 0;
4042
+ transition: opacity 0.18s ease;
4043
+ }
4044
+ html.dark .diagram-controls {
4045
+ background: hsl(0 0% 8% / 0.85);
4046
+ }
4047
+ .diagram-container:hover .diagram-controls,
4048
+ .diagram-container:focus-within .diagram-controls {
4049
+ opacity: 1;
4050
+ }
4051
+ .diagram-ctrl-btn {
4052
+ width: 26px;
4053
+ height: 26px;
4054
+ display: inline-flex;
4055
+ align-items: center;
4056
+ justify-content: center;
4057
+ border: none;
4058
+ border-radius: 6px;
4059
+ background: transparent;
4060
+ color: var(--ink-2);
4061
+ font-size: 14px;
4062
+ line-height: 1;
4063
+ cursor: pointer;
4064
+ }
4065
+ .diagram-ctrl-btn:hover {
4066
+ background: var(--bg-soft);
4067
+ color: var(--ink);
4068
+ }
4069
+
4070
+ /* 全屏查看层 */
4071
+ .diagram-fullscreen-overlay {
4072
+ position: fixed;
4073
+ inset: 0;
4074
+ z-index: 999;
4075
+ display: flex;
4076
+ align-items: center;
4077
+ justify-content: center;
4078
+ background: hsl(0 0% 0% / 0.8);
4079
+ backdrop-filter: blur(3px);
4080
+ }
4081
+ .diagram-fs-content {
4082
+ width: 94vw;
4083
+ height: 86vh;
4084
+ display: flex;
4085
+ align-items: center;
4086
+ justify-content: center;
4087
+ overflow: hidden;
4088
+ cursor: grab;
4089
+ }
4090
+ .diagram-fs-content svg,
4091
+ .diagram-fs-content img {
4092
+ max-width: 100%;
4093
+ max-height: 100%;
4094
+ }
4095
+ .diagram-fs-controls {
4096
+ position: absolute;
4097
+ top: 18px;
4098
+ right: 18px;
4099
+ display: flex;
4100
+ gap: 4px;
4101
+ padding: 4px;
4102
+ background: hsl(0 0% 100% / 0.92);
4103
+ border-radius: var(--radius-sm);
4104
+ box-shadow: var(--shadow-md);
4105
+ }
4106
+ html.dark .diagram-fs-controls {
4107
+ background: hsl(0 0% 12% / 0.92);
4108
+ }
4109
+ .diagram-fs-controls .diagram-ctrl-btn {
4110
+ width: 30px;
4111
+ height: 30px;
4112
+ font-size: 16px;
4113
+ }
4114
+
4115
+ /* KaTeX:宽公式横向滚动而非撑破版心 */
4116
+ .katex-display {
4117
+ overflow-x: auto;
4118
+ overflow-y: hidden;
4119
+ padding: 4px 0;
4120
+ }
4121
+ /* math 块(§4.61 起):rehype-katex 先于 EC 执行,产物直接落入 .prose,
4122
+ KaTeX 取 currentColor 随 .prose 的 var(--ink) 自动适配双主题 */
4123
+
4124
+ /* 邮箱防爬:href 已置 '#',保持可点击的视觉暗示 */
4125
+ a[data-encoded-email] {
4126
+ cursor: pointer;
4127
+ }
4128
+
4129
+ /* 加密文章(M3b-b7):锁卡 + 解密容器 + meta 锁标 */
4130
+ .enc-flag {
4131
+ color: var(--accent);
4132
+ }
4133
+ .enc-box {
4134
+ display: flex;
4135
+ justify-content: center;
4136
+ padding: 3rem 1rem;
4137
+ }
4138
+ .enc-card {
4139
+ display: flex;
4140
+ flex-direction: column;
4141
+ align-items: center;
4142
+ gap: 10px;
4143
+ width: 100%;
4144
+ max-width: 360px;
4145
+ padding: 2rem 1.5rem;
4146
+ background: var(--surface);
4147
+ border: 1px solid var(--border);
4148
+ border-radius: var(--radius);
4149
+ box-shadow: var(--shadow-sm);
4150
+ text-align: center;
4151
+ }
4152
+ .enc-icon {
4153
+ width: 44px;
4154
+ height: 44px;
4155
+ color: var(--accent);
4156
+ }
4157
+ .enc-title {
4158
+ margin: 0;
4159
+ font-family: var(--font-display);
4160
+ font-size: 1.05rem;
4161
+ font-weight: 700;
4162
+ }
4163
+ .enc-desc {
4164
+ margin: 0;
4165
+ font-size: 0.85rem;
4166
+ color: var(--ink-2);
4167
+ }
4168
+ .enc-hint {
4169
+ margin: 0;
4170
+ font-size: 0.78rem;
4171
+ color: var(--muted);
4172
+ }
4173
+ .enc-form {
4174
+ display: flex;
4175
+ flex-direction: column;
4176
+ gap: 10px;
4177
+ width: 100%;
4178
+ margin-top: 6px;
4179
+ }
4180
+ .enc-form input {
4181
+ width: 100%;
4182
+ padding: 9px 12px;
4183
+ font-size: 0.9rem;
4184
+ color: var(--ink);
4185
+ background: var(--bg);
4186
+ border: 1px solid var(--border);
4187
+ border-radius: var(--radius-sm);
4188
+ outline: none;
4189
+ transition: border-color 0.15s ease;
4190
+ }
4191
+ .enc-form input:focus {
4192
+ border-color: var(--accent);
4193
+ }
4194
+ .enc-form button {
4195
+ padding: 9px 12px;
4196
+ font-size: 0.9rem;
4197
+ font-weight: 500;
4198
+ cursor: pointer;
4199
+ color: #fff;
4200
+ background: var(--accent);
4201
+ border: none;
4202
+ border-radius: var(--radius-sm);
4203
+ transition:
4204
+ filter 0.15s ease,
4205
+ transform 0.1s ease;
4206
+ }
4207
+ .enc-form button:hover {
4208
+ filter: brightness(1.06);
4209
+ }
4210
+ .enc-form button:active {
4211
+ transform: scale(0.98);
4212
+ }
4213
+ .enc-error {
4214
+ margin: 0;
4215
+ font-size: 0.78rem;
4216
+ color: #d4574e;
4217
+ }
4218
+
4219
+ @media (max-width: 640px) {
4220
+ /* 触屏无 hover:图表控制栏常显 */
4221
+ .diagram-controls {
4222
+ opacity: 1;
4223
+ }
4224
+ }
4225
+
4226
+ /* ---------- 17. 相关/随机文章推荐(M3b-b9) ---------- */
4227
+ .related-grid {
4228
+ display: grid;
4229
+ /* minmax(0,1fr) 防止轨道被 nowrap 标题的 min-content 撑破页面 */
4230
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4231
+ gap: 16px;
4232
+ margin: 28px 0;
4233
+ }
4234
+ .related-card {
4235
+ display: flex;
4236
+ flex-direction: column;
4237
+ /* 同原版 card-base:min-width:0 + overflow:hidden 保证截断链生效 */
4238
+ min-width: 0;
4239
+ overflow: hidden;
4240
+ padding: 18px 20px;
4241
+ background: var(--surface);
4242
+ border: 1px solid var(--border);
4243
+ border-radius: var(--radius);
4244
+ box-shadow: var(--shadow-sm);
4245
+ }
4246
+ .related-head {
4247
+ display: flex;
4248
+ align-items: center;
4249
+ gap: 8px;
4250
+ padding-bottom: 12px;
4251
+ margin-bottom: 6px;
4252
+ font-family: var(--font-display);
4253
+ font-size: 0.95rem;
4254
+ font-weight: 700;
4255
+ border-bottom: 1px dashed var(--border);
4256
+ }
4257
+ .related-head svg {
4258
+ width: 18px;
4259
+ height: 18px;
4260
+ flex-shrink: 0;
4261
+ color: var(--accent);
4262
+ }
4263
+ .related-badge {
4264
+ margin-left: auto;
4265
+ padding: 2px 8px;
4266
+ font-size: 0.68rem;
4267
+ font-weight: 500;
4268
+ letter-spacing: 0.02em;
4269
+ color: var(--accent-ink);
4270
+ background: var(--accent-soft);
4271
+ border-radius: 999px;
4272
+ }
4273
+ .related-list {
4274
+ display: flex;
4275
+ flex-direction: column;
4276
+ flex: 1;
4277
+ }
4278
+ .related-item {
4279
+ display: flex;
4280
+ align-items: center;
4281
+ gap: 10px;
4282
+ padding: 10px 8px;
4283
+ margin: 0 -8px;
4284
+ border-radius: var(--radius-sm);
4285
+ transition: background-color 0.15s ease;
4286
+ }
4287
+ .related-item + .related-item {
4288
+ border-top: 1px dashed var(--border);
4289
+ }
4290
+ .related-item:hover {
4291
+ background: var(--bg-soft);
4292
+ }
4293
+ .related-num {
4294
+ display: inline-flex;
4295
+ align-items: center;
4296
+ justify-content: center;
4297
+ width: 24px;
4298
+ height: 24px;
4299
+ flex-shrink: 0;
4300
+ font-size: 0.75rem;
4301
+ font-weight: 700;
4302
+ color: var(--accent-ink);
4303
+ background: var(--accent-soft);
4304
+ border-radius: var(--radius-sm);
4305
+ }
4306
+ .related-body {
4307
+ display: flex;
4308
+ flex-direction: column;
4309
+ gap: 3px;
4310
+ flex: 1;
4311
+ min-width: 0;
4312
+ }
4313
+ .related-title {
4314
+ font-size: 0.875rem;
4315
+ font-weight: 700;
4316
+ color: var(--ink);
4317
+ white-space: nowrap;
4318
+ overflow: hidden;
4319
+ text-overflow: ellipsis;
4320
+ transition: color 0.15s ease;
4321
+ }
4322
+ .related-item:hover .related-title {
4323
+ color: var(--accent-ink);
4324
+ }
4325
+ .related-meta {
4326
+ display: flex;
4327
+ align-items: center;
4328
+ gap: 8px;
4329
+ min-width: 0;
4330
+ font-size: 0.75rem;
4331
+ color: var(--muted);
4332
+ }
4333
+ .related-cat {
4334
+ flex-shrink: 0;
4335
+ padding: 1px 7px;
4336
+ font-size: 0.68rem;
4337
+ color: var(--ink-2);
4338
+ background: var(--bg-soft);
4339
+ border-radius: 999px;
4340
+ }
4341
+ .related-desc {
4342
+ white-space: nowrap;
4343
+ overflow: hidden;
4344
+ text-overflow: ellipsis;
4345
+ }
4346
+ .related-arrow {
4347
+ width: 18px;
4348
+ height: 18px;
4349
+ flex-shrink: 0;
4350
+ color: var(--muted);
4351
+ transition:
4352
+ color 0.15s ease,
4353
+ transform 0.15s ease;
4354
+ }
4355
+ .related-item:hover .related-arrow {
4356
+ color: var(--accent);
4357
+ transform: translateX(2px);
4358
+ }
4359
+ .related-empty {
4360
+ display: flex;
4361
+ flex-direction: column;
4362
+ align-items: center;
4363
+ justify-content: center;
4364
+ gap: 8px;
4365
+ flex: 1;
4366
+ min-height: 140px;
4367
+ font-size: 0.85rem;
4368
+ color: var(--muted);
4369
+ }
4370
+ .related-empty svg {
4371
+ width: 32px;
4372
+ height: 32px;
4373
+ opacity: 0.5;
4374
+ }
4375
+
4376
+ @media (max-width: 860px) {
4377
+ .related-grid {
4378
+ grid-template-columns: 1fr;
4379
+ }
4380
+ }
4381
+
4382
+ /* ---------- 18. LQIP 占位渐变(M3b-b9) ---------- */
4383
+ /* 占位层绝对定位盖在 img 上(z-index 低于各容器内徽标/文案 z-index 1/2);
4384
+ 图片在下方正常加载,加载完成后容器加 .qy-img-in 驱动占位淡出。
4385
+ 不给 img 加 opacity/transition,避免覆盖 .post-cover img 的 hover 缩放过渡 */
4386
+ .qy-lqip {
4387
+ position: absolute;
4388
+ inset: 0;
4389
+ z-index: 0;
4390
+ pointer-events: none;
4391
+ transition: opacity 0.6s ease;
4392
+ }
4393
+ .qy-img-in > .qy-lqip {
4394
+ opacity: 0;
4395
+ }
4396
+ @media (prefers-reduced-motion: reduce) {
4397
+ .qy-lqip {
4398
+ transition: none;
4399
+ }
4400
+ }
4401
+
4402
+ /* ---------- 19. 分享海报(M3b-b9) ---------- */
4403
+ /* 文章页支持卡(打赏 + 分享海报入口) */
4404
+ .support-card {
4405
+ margin-top: 28px;
4406
+ display: flex;
4407
+ align-items: center;
4408
+ justify-content: space-between;
4409
+ gap: 18px;
4410
+ padding: 18px 22px;
4411
+ border: 1px dashed var(--border);
4412
+ border-radius: 14px;
4413
+ background: var(--surface);
4414
+ }
4415
+ .support-info h3 {
4416
+ margin: 0;
4417
+ font-size: 1rem;
4418
+ color: var(--ink);
4419
+ }
4420
+ .support-info p {
4421
+ margin: 4px 0 0;
4422
+ font-size: 0.85rem;
4423
+ color: var(--muted);
4424
+ }
4425
+ .support-actions {
4426
+ display: flex;
4427
+ align-items: center;
4428
+ gap: 10px;
4429
+ flex-shrink: 0;
4430
+ }
4431
+ .btn-sponsor {
4432
+ display: inline-flex;
4433
+ align-items: center;
4434
+ gap: 8px;
4435
+ padding: 10px 22px;
4436
+ border: 1px solid var(--accent);
4437
+ border-radius: 999px;
4438
+ background: var(--accent-soft);
4439
+ color: var(--accent-deep);
4440
+ font-size: 0.875rem;
4441
+ text-decoration: none;
4442
+ transition:
4443
+ background 0.2s ease,
4444
+ color 0.2s ease;
4445
+ }
4446
+ .btn-sponsor:hover {
4447
+ background: var(--accent);
4448
+ color: var(--surface);
4449
+ }
4450
+ .btn-sponsor svg {
4451
+ width: 15px;
4452
+ height: 15px;
4453
+ }
4454
+ @media (max-width: 640px) {
4455
+ .support-card {
4456
+ flex-direction: column;
4457
+ align-items: stretch;
4458
+ text-align: center;
4459
+ }
4460
+ .support-actions {
4461
+ justify-content: center;
4462
+ }
4463
+ }
4464
+ .btn-poster {
4465
+ display: inline-flex;
4466
+ align-items: center;
4467
+ gap: 8px;
4468
+ padding: 10px 22px;
4469
+ border: 1px solid var(--border);
4470
+ border-radius: 999px;
4471
+ background: transparent;
4472
+ color: var(--muted);
4473
+ font-size: 0.875rem;
4474
+ cursor: pointer;
4475
+ transition:
4476
+ color 0.2s ease,
4477
+ border-color 0.2s ease;
4478
+ }
4479
+ .btn-poster:hover {
4480
+ color: var(--accent);
4481
+ border-color: var(--accent);
4482
+ }
4483
+ .btn-poster svg {
4484
+ width: 15px;
4485
+ height: 15px;
4486
+ }
4487
+
4488
+ /* 弹窗(z-index 高于 lightbox 320);海报 PNG 固定白底,卡片头部/底部跟随主题 */
4489
+ .poster-modal {
4490
+ position: fixed;
4491
+ inset: 0;
4492
+ z-index: 330;
4493
+ display: flex;
4494
+ align-items: center;
4495
+ justify-content: center;
4496
+ padding: 20px;
4497
+ background: rgba(0, 0, 0, 0.5);
4498
+ backdrop-filter: blur(4px);
4499
+ animation: poster-fade 0.2s ease;
4500
+ }
4501
+ @keyframes poster-fade {
4502
+ from {
4503
+ opacity: 0;
4504
+ }
4505
+ }
4506
+ .poster-card {
4507
+ display: flex;
4508
+ flex-direction: column;
4509
+ width: min(480px, 92vw);
4510
+ max-height: 88vh;
4511
+ background: var(--surface);
4512
+ border: 1px solid var(--border);
4513
+ border-radius: 14px;
4514
+ box-shadow: var(--shadow-md);
4515
+ overflow: hidden;
4516
+ animation: poster-pop 0.25s ease;
4517
+ }
4518
+ @keyframes poster-pop {
4519
+ from {
4520
+ opacity: 0;
4521
+ transform: translateY(12px) scale(0.98);
4522
+ }
4523
+ }
4524
+ .poster-head {
4525
+ display: flex;
4526
+ align-items: center;
4527
+ justify-content: space-between;
4528
+ padding: 12px 16px;
4529
+ border-bottom: 1px solid var(--border);
4530
+ }
4531
+ .poster-head strong {
4532
+ font-size: 0.95rem;
4533
+ color: var(--ink);
4534
+ }
4535
+ .poster-close {
4536
+ display: inline-flex;
4537
+ align-items: center;
4538
+ justify-content: center;
4539
+ width: 30px;
4540
+ height: 30px;
4541
+ border: none;
4542
+ border-radius: var(--radius-sm);
4543
+ background: transparent;
4544
+ color: var(--muted);
4545
+ cursor: pointer;
4546
+ transition:
4547
+ background 0.2s ease,
4548
+ color 0.2s ease;
4549
+ }
4550
+ .poster-close:hover {
4551
+ background: var(--bg-soft);
4552
+ color: var(--ink);
4553
+ }
4554
+ .poster-stage {
4555
+ flex: 1;
4556
+ overflow: auto;
4557
+ padding: 16px;
4558
+ }
4559
+ .poster-img {
4560
+ display: block;
4561
+ width: 100%;
4562
+ height: auto;
4563
+ border-radius: var(--radius-sm);
4564
+ }
4565
+ .poster-loading {
4566
+ display: flex;
4567
+ align-items: center;
4568
+ justify-content: center;
4569
+ gap: 10px;
4570
+ min-height: 160px;
4571
+ color: var(--muted);
4572
+ font-size: 0.875rem;
4573
+ }
4574
+ .poster-spinner {
4575
+ width: 18px;
4576
+ height: 18px;
4577
+ border-radius: 50%;
4578
+ border: 2px solid var(--border);
4579
+ border-top-color: var(--accent);
4580
+ animation: poster-spin 0.8s linear infinite;
4581
+ }
4582
+ @keyframes poster-spin {
4583
+ to {
4584
+ transform: rotate(360deg);
4585
+ }
4586
+ }
4587
+ .poster-foot {
4588
+ display: flex;
4589
+ gap: 10px;
4590
+ padding: 12px 16px;
4591
+ border-top: 1px solid var(--border);
4592
+ }
4593
+ .poster-btn {
4594
+ flex: 1;
4595
+ padding: 9px 0;
4596
+ border: 1px solid var(--border);
4597
+ border-radius: 9px;
4598
+ background: transparent;
4599
+ color: var(--muted);
4600
+ font-size: 0.875rem;
4601
+ cursor: pointer;
4602
+ transition:
4603
+ color 0.2s ease,
4604
+ border-color 0.2s ease;
4605
+ }
4606
+ .poster-btn:hover:not(:disabled) {
4607
+ color: var(--accent);
4608
+ border-color: var(--accent);
4609
+ }
4610
+ .poster-btn:disabled {
4611
+ opacity: 0.5;
4612
+ cursor: not-allowed;
4613
+ }
4614
+ @media (prefers-reduced-motion: reduce) {
4615
+ .poster-modal,
4616
+ .poster-card {
4617
+ animation: none;
4618
+ }
4619
+ .poster-spinner {
4620
+ animation-duration: 2s;
4621
+ }
4622
+ }
4623
+
4624
+ /* ------------------------------------------- image-grid([grid] 图片网格) */
4625
+ .image-grid {
4626
+ display: grid;
4627
+ grid-template-columns: 1fr;
4628
+ align-items: stretch;
4629
+ gap: 1rem;
4630
+ margin: 1.5rem 0;
4631
+ }
4632
+ @media (min-width: 768px) {
4633
+ .image-grid[data-cols="2"] {
4634
+ grid-template-columns: repeat(2, 1fr);
4635
+ }
4636
+ .image-grid[data-cols="3"] {
4637
+ grid-template-columns: repeat(3, 1fr);
4638
+ }
4639
+ .image-grid[data-cols="4"] {
4640
+ grid-template-columns: repeat(4, 1fr);
4641
+ }
4642
+ }
4643
+ .image-grid img {
4644
+ width: 100%;
4645
+ height: 100%;
4646
+ object-fit: cover;
4647
+ border-radius: var(--radius-sm);
4648
+ }
4649
+ /* 覆盖 .prose figure 的边框/背景(网格内图片铺满格子) */
4650
+ .image-grid figure {
4651
+ display: flex;
4652
+ flex-direction: column;
4653
+ height: 100%;
4654
+ width: 100%;
4655
+ margin: 0;
4656
+ padding: 0;
4657
+ border: none;
4658
+ overflow: hidden;
4659
+ border-radius: var(--radius-sm);
4660
+ }
4661
+ .image-grid figure img {
4662
+ flex-grow: 1;
4663
+ min-height: 0;
4664
+ }
4665
+ .image-grid figcaption {
4666
+ margin-top: 0.5rem;
4667
+ margin-bottom: 0;
4668
+ padding: 0 2px;
4669
+ background: transparent;
4670
+ color: var(--ink-2);
4671
+ }
4672
+
4673
+ /* --------------------------------------- card-github(GitHub 仓库卡片) */
4674
+ /* 注意:卡片是 .prose 内的 a 元素,必须覆盖 .prose a 的 border-bottom accent */
4675
+ .prose a.card-github {
4676
+ display: block;
4677
+ position: relative;
4678
+ margin: 1.25rem 0;
4679
+ padding: 1.1rem 1.5rem;
4680
+ color: var(--ink);
4681
+ background: var(--bg-soft);
4682
+ border: 1px solid var(--border);
4683
+ border-radius: var(--radius);
4684
+ text-decoration: none;
4685
+ }
4686
+ .prose a.card-github:hover {
4687
+ background: var(--accent-soft);
4688
+ color: var(--accent-ink);
4689
+ }
4690
+ .prose a.card-github:hover .gc-titlebar {
4691
+ color: var(--accent-ink);
4692
+ }
4693
+ .prose a.card-github:hover .gc-stars,
4694
+ .prose a.card-github:hover .gc-forks,
4695
+ .prose a.card-github:hover .gc-license,
4696
+ .prose a.card-github:hover .gc-description {
4697
+ color: var(--ink);
4698
+ }
4699
+ .prose a.card-github:hover .gc-stars::before,
4700
+ .prose a.card-github:hover .gc-forks::before,
4701
+ .prose a.card-github:hover .gc-license::before {
4702
+ background-color: var(--ink);
4703
+ }
4704
+ .prose a.card-github:active {
4705
+ scale: 0.98;
4706
+ }
4707
+ .prose a.card-github .gc-titlebar {
4708
+ display: flex;
4709
+ align-items: center;
4710
+ justify-content: space-between;
4711
+ margin-bottom: 0.5rem;
4712
+ color: var(--ink);
4713
+ font-size: 1.25rem;
4714
+ font-weight: 500;
4715
+ }
4716
+ .prose a.card-github .gc-titlebar-left {
4717
+ display: flex;
4718
+ flex-flow: row nowrap;
4719
+ gap: 0.5rem;
4720
+ }
4721
+ .prose a.card-github .gc-repo {
4722
+ font-weight: bold;
4723
+ }
4724
+ .prose a.card-github .gc-owner {
4725
+ position: relative;
4726
+ display: flex;
4727
+ flex-flow: row nowrap;
4728
+ align-items: center;
4729
+ gap: 0.5rem;
4730
+ font-weight: 300;
4731
+ }
4732
+ .prose a.card-github .gc-avatar {
4733
+ display: block;
4734
+ overflow: hidden;
4735
+ width: 1.5rem;
4736
+ height: 1.5rem;
4737
+ margin-top: -0.1rem;
4738
+ background-color: var(--accent);
4739
+ background-size: cover;
4740
+ border-radius: 50%;
4741
+ }
4742
+ .prose a.card-github .gc-description {
4743
+ margin-bottom: 0.7rem;
4744
+ font-size: 1rem;
4745
+ font-weight: 300;
4746
+ line-height: 1.5rem;
4747
+ color: var(--ink-2);
4748
+ }
4749
+ .prose a.card-github .gc-infobar {
4750
+ display: flex;
4751
+ flex-flow: row nowrap;
4752
+ gap: 1.5rem;
4753
+ width: fit-content;
4754
+ color: var(--ink-2);
4755
+ }
4756
+ .prose a.card-github .gc-language {
4757
+ display: none;
4758
+ }
4759
+ .prose a.card-github .gc-stars,
4760
+ .prose a.card-github .gc-forks,
4761
+ .prose a.card-github .gc-license,
4762
+ .prose a.card-github .github-logo {
4763
+ font-weight: 500;
4764
+ font-size: 0.875rem;
4765
+ opacity: 0.9;
4766
+ }
4767
+ .prose a.card-github .gc-stars::before,
4768
+ .prose a.card-github .gc-forks::before,
4769
+ .prose a.card-github .gc-license::before,
4770
+ .prose a.card-github .github-logo::before {
4771
+ content: " ";
4772
+ display: inline-block;
4773
+ height: 1.3em;
4774
+ width: 1.3em;
4775
+ margin-right: 0.4rem;
4776
+ vertical-align: -0.24em;
4777
+ font-size: inherit;
4778
+ background-color: var(--ink-2);
4779
+ overflow: visible;
4780
+ -webkit-mask-size: contain;
4781
+ mask-size: contain;
4782
+ -webkit-mask-position: center;
4783
+ mask-position: center;
4784
+ -webkit-mask-repeat: no-repeat;
4785
+ mask-repeat: no-repeat;
4786
+ transition-property: background-color, background;
4787
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
4788
+ transition-duration: 0.15s;
4789
+ }
4790
+ .prose a.card-github .gc-stars::before {
4791
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z'%3E%3C/path%3E%3C/svg%3E");
4792
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8 .25a.75.75 0 0 1 .673.418l1.882 3.815 4.21.612a.75.75 0 0 1 .416 1.279l-3.046 2.97.719 4.192a.751.751 0 0 1-1.088.791L8 12.347l-3.766 1.98a.75.75 0 0 1-1.088-.79l.72-4.194L.818 6.374a.75.75 0 0 1 .416-1.28l4.21-.611L7.327.668A.75.75 0 0 1 8 .25Zm0 2.445L6.615 5.5a.75.75 0 0 1-.564.41l-3.097.45 2.24 2.184a.75.75 0 0 1 .216.664l-.528 3.084 2.769-1.456a.75.75 0 0 1 .698 0l2.77 1.456-.53-3.084a.75.75 0 0 1 .216-.664l2.24-2.183-3.096-.45a.75.75 0 0 1-.564-.41L8 2.694Z'%3E%3C/path%3E%3C/svg%3E");
4793
+ }
4794
+ .prose a.card-github .gc-license::before {
4795
+ margin-right: 0.5rem;
4796
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z'%3E%3C/path%3E%3C/svg%3E");
4797
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M8.75.75V2h.985c.304 0 .603.08.867.231l1.29.736c.038.022.08.033.124.033h2.234a.75.75 0 0 1 0 1.5h-.427l2.111 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.006.005-.01.01-.045.04c-.21.176-.441.327-.686.45C14.556 10.78 13.88 11 13 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L12.178 4.5h-.162c-.305 0-.604-.079-.868-.231l-1.29-.736a.245.245 0 0 0-.124-.033H8.75V13h2.5a.75.75 0 0 1 0 1.5h-6.5a.75.75 0 0 1 0-1.5h2.5V3.5h-.984a.245.245 0 0 0-.124.033l-1.289.737c-.265.15-.564.23-.869.23h-.162l2.112 4.692a.75.75 0 0 1-.154.838l-.53-.53.529.531-.001.002-.002.002-.006.006-.016.015-.045.04c-.21.176-.441.327-.686.45C4.556 10.78 3.88 11 3 11a4.498 4.498 0 0 1-2.023-.454 3.544 3.544 0 0 1-.686-.45l-.045-.04-.016-.015-.006-.006-.004-.004v-.001a.75.75 0 0 1-.154-.838L2.178 4.5H1.75a.75.75 0 0 1 0-1.5h2.234a.249.249 0 0 0 .125-.033l1.288-.737c.265-.15.564-.23.869-.23h.984V.75a.75.75 0 0 1 1.5 0Zm2.945 8.477c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L13 6.327Zm-10 0c.285.135.718.273 1.305.273s1.02-.138 1.305-.273L3 6.327Z'%3E%3C/path%3E%3C/svg%3E");
4798
+ }
4799
+ .prose a.card-github .gc-forks::before {
4800
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z'%3E%3C/path%3E%3C/svg%3E");
4801
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' height='16' viewBox='0 0 16 16' version='1.1' width='16'%3E%3Cpath d='M5 5.372v.878c0 .414.336.75.75.75h4.5a.75.75 0 0 0 .75-.75v-.878a2.25 2.25 0 1 1 1.5 0v.878a2.25 2.25 0 0 1-2.25 2.25h-1.5v2.128a2.251 2.251 0 1 1-1.5 0V8.5h-1.5A2.25 2.25 0 0 1 3.5 6.25v-.878a2.25 2.25 0 1 1 1.5 0ZM5 3.25a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Zm6.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5Zm-3 8.75a.75.75 0 1 0-1.5 0 .75.75 0 0 0 1.5 0Z'%3E%3C/path%3E%3C/svg%3E");
4802
+ }
4803
+ .prose a.card-github .github-logo {
4804
+ font-size: 1.25rem;
4805
+ }
4806
+ .prose a.card-github .github-logo::before {
4807
+ margin-right: 0;
4808
+ background-color: var(--ink);
4809
+ -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31' height='32' viewBox='0 0 496 512'%3E%3Cpath fill='%23a1f7cb' d='M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2'/%3E%3C/svg%3E");
4810
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='31' height='32' viewBox='0 0 496 512'%3E%3Cpath fill='%23a1f7cb' d='M165.9 397.4c0 2-2.3 3.6-5.2 3.6c-3.3.3-5.6-1.3-5.6-3.6c0-2 2.3-3.6 5.2-3.6c3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9c2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9c.3 2 2.9 3.3 5.9 2.6c2.9-.7 4.9-2.6 4.6-4.6c-.3-1.9-3-3.2-5.9-2.9M244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2c12.8 2.3 17.3-5.6 17.3-12.1c0-6.2-.3-40.4-.3-61.4c0 0-70 15-84.7-29.8c0 0-11.4-29.1-27.8-36.6c0 0-22.9-15.7 1.6-15.4c0 0 24.9 2 38.6 25.8c21.9 38.6 58.6 27.5 72.9 20.9c2.3-16 8.8-27.1 16-33.7c-55.9-6.2-112.3-14.3-112.3-110.5c0-27.5 7.6-41.3 23.6-58.9c-2.6-6.5-11.1-33.3 2.6-67.9c20.9-6.5 69 27 69 27c20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27c13.7 34.7 5.2 61.4 2.6 67.9c16 17.7 25.8 31.5 25.8 58.9c0 96.5-58.9 104.2-114.8 110.5c9.2 7.9 17 22.9 17 46.4c0 33.7-.3 75.4-.3 83.6c0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252C496 113.3 383.5 8 244.8 8M97.2 352.9c-1.3 1-1 3.3.7 5.2c1.6 1.6 3.9 2.3 5.2 1c1.3-1 1-3.3-.7-5.2c-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9c1.6 1 3.6.7 4.3-.7c.7-1.3-.3-2.9-2.3-3.9c-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2c2.3 2.3 5.2 2.6 6.5 1c1.3-1.3.7-4.3-1.3-6.2c-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9c1.6 2.3 4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2c-1.4-2.3-4-3.3-5.6-2'/%3E%3C/svg%3E");
4811
+ }
4812
+ .prose a.card-github.fetch-waiting {
4813
+ pointer-events: none;
4814
+ opacity: 0.7;
4815
+ transition: opacity 0.15s ease-in-out;
4816
+ }
4817
+ .prose a.card-github.fetch-waiting .gc-description,
4818
+ .prose a.card-github.fetch-waiting .gc-infobar,
4819
+ .prose a.card-github.fetch-waiting .gc-avatar {
4820
+ background-color: var(--ink-2);
4821
+ color: transparent;
4822
+ opacity: 0.5;
4823
+ animation: card-pulsate 2s infinite linear;
4824
+ user-select: none;
4825
+ }
4826
+ .prose a.card-github.fetch-waiting .gc-description::before,
4827
+ .prose a.card-github.fetch-waiting .gc-infobar::before,
4828
+ .prose a.card-github.fetch-waiting .gc-avatar::before {
4829
+ background-color: transparent;
4830
+ }
4831
+ .prose a.card-github.fetch-waiting .gc-repo {
4832
+ margin-left: -0.1rem;
4833
+ }
4834
+ .prose a.card-github.fetch-waiting .gc-description,
4835
+ .prose a.card-github.fetch-waiting .gc-infobar {
4836
+ border-radius: 0.5rem;
4837
+ }
4838
+ .prose a.card-github.fetch-error {
4839
+ pointer-events: all;
4840
+ opacity: 1;
4841
+ }
4842
+ @keyframes card-pulsate {
4843
+ 0% {
4844
+ opacity: 0.15;
4845
+ }
4846
+ 50% {
4847
+ opacity: 0.25;
4848
+ }
4849
+ 100% {
4850
+ opacity: 0.15;
4851
+ }
4852
+ }
4853
+ .prose a.card-github,
4854
+ .prose a.card-github .gc-description,
4855
+ .prose a.card-github .gc-titlebar,
4856
+ .prose a.card-github .gc-stars,
4857
+ .prose a.card-github .gc-forks,
4858
+ .prose a.card-github .gc-license,
4859
+ .prose a.card-github .gc-avatar,
4860
+ .prose a.card-github .github-logo {
4861
+ transition-property: all;
4862
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
4863
+ transition-duration: 0.15s;
4864
+ }