@windcoder/astro-theme-orchid 0.0.0-stage → 0.1.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 (82) hide show
  1. package/README.md +311 -2
  2. package/package.json +68 -3
  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 +406 -0
  39. package/src/plugins/plantuml-encoder.ts +95 -0
  40. package/src/plugins/rehype-diagram.ts +218 -0
  41. package/src/plugins/rehype-email.ts +75 -0
  42. package/src/plugins/rehype-github-card.ts +114 -0
  43. package/src/plugins/rehype.ts +284 -0
  44. package/src/plugins/remark-diagram.ts +78 -0
  45. package/src/plugins/remark-directives.ts +100 -0
  46. package/src/plugins/remark-excerpt.ts +29 -0
  47. package/src/plugins/remark-image-grid.ts +97 -0
  48. package/src/plugins/remark-reading-time.ts +38 -0
  49. package/src/plugins/scripts/diagram-panzoom.js +388 -0
  50. package/src/plugins/scripts/plantuml-theme-switch.js +90 -0
  51. package/src/routes/404.astro +14 -0
  52. package/src/routes/_hydrate.ts +34 -0
  53. package/src/routes/about.astro +25 -0
  54. package/src/routes/api/allPostMeta.json.ts +26 -0
  55. package/src/routes/archive.astro +81 -0
  56. package/src/routes/categories/[category].astro +37 -0
  57. package/src/routes/categories/index.astro +29 -0
  58. package/src/routes/friends.astro +83 -0
  59. package/src/routes/gallery/[album].astro +97 -0
  60. package/src/routes/gallery/index.astro +100 -0
  61. package/src/routes/guestbook.astro +37 -0
  62. package/src/routes/index.astro +47 -0
  63. package/src/routes/og/[...slug].ts +281 -0
  64. package/src/routes/page/[page].astro +53 -0
  65. package/src/routes/posts/[...slug].astro +337 -0
  66. package/src/routes/robots.txt.ts +18 -0
  67. package/src/routes/rss.xml.ts +37 -0
  68. package/src/routes/series/[name].astro +63 -0
  69. package/src/routes/series/index.astro +64 -0
  70. package/src/routes/sponsor.astro +84 -0
  71. package/src/routes/tags/[tag].astro +40 -0
  72. package/src/routes/tags/index.astro +29 -0
  73. package/src/schema.ts +1212 -0
  74. package/src/scripts/app.ts +1041 -0
  75. package/src/scripts/share-poster.ts +468 -0
  76. package/src/styles/global.css +4830 -0
  77. package/src/utils/crypto.ts +46 -0
  78. package/src/utils/gallery.ts +76 -0
  79. package/src/utils/lqip.ts +18 -0
  80. package/src/utils/related.ts +101 -0
  81. package/src/utils.ts +181 -0
  82. package/src/vite.ts +105 -0
@@ -0,0 +1,4830 @@
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
+ .series-link {
2709
+ display: flex;
2710
+ align-items: center;
2711
+ gap: 14px;
2712
+ padding: 14px 18px;
2713
+ }
2714
+ .series-idx {
2715
+ flex: none;
2716
+ width: 26px;
2717
+ height: 26px;
2718
+ display: inline-flex;
2719
+ align-items: center;
2720
+ justify-content: center;
2721
+ border-radius: 50%;
2722
+ background: var(--accent-soft);
2723
+ color: var(--accent-deep);
2724
+ font-size: 13px;
2725
+ font-weight: 700;
2726
+ font-variant-numeric: tabular-nums;
2727
+ }
2728
+ .series-title {
2729
+ flex: 1;
2730
+ min-width: 0;
2731
+ font-weight: 600;
2732
+ color: var(--ink);
2733
+ overflow: hidden;
2734
+ text-overflow: ellipsis;
2735
+ white-space: nowrap;
2736
+ }
2737
+ .series-link:hover .series-title {
2738
+ color: var(--accent-deep);
2739
+ }
2740
+ .series-date {
2741
+ flex: none;
2742
+ font-size: 13px;
2743
+ color: var(--muted);
2744
+ font-variant-numeric: tabular-nums;
2745
+ }
2746
+ /* 文章页专题导航卡(§4.31):目录超 6 项限高滚动 */
2747
+ .series-nav {
2748
+ margin: 0 0 28px;
2749
+ padding: 16px 20px;
2750
+ }
2751
+ .series-nav-head {
2752
+ display: flex;
2753
+ align-items: center;
2754
+ justify-content: space-between;
2755
+ gap: 12px;
2756
+ flex-wrap: wrap;
2757
+ margin-bottom: 10px;
2758
+ }
2759
+ .series-nav-title {
2760
+ display: inline-flex;
2761
+ align-items: center;
2762
+ gap: 8px;
2763
+ font-size: 15.5px;
2764
+ font-weight: 700;
2765
+ color: var(--ink);
2766
+ }
2767
+ .series-nav-title svg {
2768
+ width: 16px;
2769
+ height: 16px;
2770
+ color: var(--accent);
2771
+ }
2772
+ .series-nav-progress {
2773
+ display: inline-flex;
2774
+ align-items: center;
2775
+ gap: 10px;
2776
+ font-size: 13px;
2777
+ }
2778
+ .series-nav-progress a {
2779
+ color: var(--accent);
2780
+ }
2781
+ .series-nav-progress a:hover {
2782
+ text-decoration: underline;
2783
+ }
2784
+ .series-nav-count {
2785
+ color: var(--muted);
2786
+ font-variant-numeric: tabular-nums;
2787
+ }
2788
+ .series-nav-list {
2789
+ list-style: none;
2790
+ margin: 0;
2791
+ padding: 0;
2792
+ max-height: 280px;
2793
+ overflow-y: auto;
2794
+ display: grid;
2795
+ gap: 2px;
2796
+ }
2797
+ .series-nav-item {
2798
+ position: relative;
2799
+ padding-left: 14px;
2800
+ }
2801
+ .series-nav-item::before {
2802
+ content: "";
2803
+ position: absolute;
2804
+ left: 2px;
2805
+ top: 50%;
2806
+ transform: translateY(-50%);
2807
+ width: 5px;
2808
+ height: 5px;
2809
+ border-radius: 50%;
2810
+ background: var(--border);
2811
+ }
2812
+ .series-nav-item.cur::before {
2813
+ background: var(--accent);
2814
+ }
2815
+ .series-nav-row {
2816
+ display: flex;
2817
+ align-items: baseline;
2818
+ gap: 8px;
2819
+ padding: 4px 0;
2820
+ font-size: 14px;
2821
+ color: var(--ink-2);
2822
+ }
2823
+ a.series-nav-row:hover {
2824
+ color: var(--accent-deep);
2825
+ }
2826
+ .series-nav-idx {
2827
+ flex: none;
2828
+ min-width: 18px;
2829
+ text-align: right;
2830
+ color: var(--muted);
2831
+ font-size: 12.5px;
2832
+ font-variant-numeric: tabular-nums;
2833
+ }
2834
+ .series-nav-label {
2835
+ min-width: 0;
2836
+ overflow: hidden;
2837
+ text-overflow: ellipsis;
2838
+ white-space: nowrap;
2839
+ }
2840
+ .series-nav-item.cur .series-nav-row {
2841
+ font-weight: 600;
2842
+ color: var(--accent-deep);
2843
+ }
2844
+ html.dark .series-nav-item.cur .series-nav-row {
2845
+ color: var(--accent);
2846
+ }
2847
+ @media (max-width: 560px) {
2848
+ .series-date,
2849
+ .series-nav-count {
2850
+ display: none;
2851
+ }
2852
+ }
2853
+
2854
+ /* ---------- 8. 标签页 ---------- */
2855
+ .tag-cloud {
2856
+ display: flex;
2857
+ flex-wrap: wrap;
2858
+ gap: 14px 18px;
2859
+ align-items: baseline;
2860
+ padding: 26px 30px;
2861
+ margin-bottom: 32px;
2862
+ }
2863
+ .tag-s1 {
2864
+ font-size: 15px;
2865
+ color: var(--ink-2);
2866
+ }
2867
+ .tag-s3 {
2868
+ font-size: 24px;
2869
+ }
2870
+ .tag-cloud a {
2871
+ display: inline-block;
2872
+ line-height: 1.5;
2873
+ transition:
2874
+ color 0.15s,
2875
+ transform 0.15s;
2876
+ }
2877
+ .tag-cloud a:hover {
2878
+ transform: translateY(-2px);
2879
+ }
2880
+ .tag-cloud .tag-count {
2881
+ font-size: 0.7em;
2882
+ color: var(--muted);
2883
+ margin-left: 3px;
2884
+ vertical-align: super;
2885
+ }
2886
+ .tag-list-head {
2887
+ display: flex;
2888
+ align-items: center;
2889
+ justify-content: space-between;
2890
+ margin-bottom: 16px;
2891
+ }
2892
+ .tag-list {
2893
+ display: grid;
2894
+ gap: 14px;
2895
+ max-width: 760px;
2896
+ }
2897
+ .tag-empty {
2898
+ padding: 40px 0;
2899
+ text-align: center;
2900
+ color: var(--muted);
2901
+ }
2902
+
2903
+ /* ---------- 9. 画廊 / 友链(路由 M3b 接入) ---------- */
2904
+ .chips {
2905
+ display: flex;
2906
+ flex-wrap: wrap;
2907
+ gap: 10px;
2908
+ margin-bottom: 26px;
2909
+ }
2910
+ .gallery-grid {
2911
+ display: grid;
2912
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
2913
+ gap: 20px;
2914
+ }
2915
+ .album-card {
2916
+ overflow: hidden;
2917
+ cursor: pointer;
2918
+ transition:
2919
+ box-shadow 0.2s,
2920
+ transform 0.2s,
2921
+ border-color 0.2s;
2922
+ }
2923
+ .album-card:hover {
2924
+ box-shadow: var(--shadow-md);
2925
+ transform: translateY(-3px);
2926
+ border-color: var(--border-2);
2927
+ }
2928
+ .album-card.hidden {
2929
+ display: none;
2930
+ }
2931
+ .album-cover {
2932
+ position: relative;
2933
+ aspect-ratio: 1;
2934
+ overflow: hidden;
2935
+ }
2936
+ .album-cover img {
2937
+ width: 100%;
2938
+ height: 100%;
2939
+ object-fit: cover;
2940
+ transition: transform 0.5s ease;
2941
+ }
2942
+ .album-card:hover .album-cover img {
2943
+ transform: scale(1.04);
2944
+ }
2945
+ .album-cover .lock-badge {
2946
+ position: absolute;
2947
+ top: 12px;
2948
+ right: 12px;
2949
+ z-index: 2;
2950
+ display: inline-flex;
2951
+ align-items: center;
2952
+ gap: 5px;
2953
+ padding: 4px 12px;
2954
+ border-radius: 999px;
2955
+ font-size: 12px;
2956
+ background: rgba(0, 0, 0, 0.55);
2957
+ color: #fff;
2958
+ -webkit-backdrop-filter: blur(6px);
2959
+ backdrop-filter: blur(6px);
2960
+ }
2961
+ .album-cover .lock-badge svg {
2962
+ width: 13px;
2963
+ height: 13px;
2964
+ }
2965
+ .album-info {
2966
+ padding: 14px 18px 16px;
2967
+ display: flex;
2968
+ align-items: baseline;
2969
+ gap: 10px;
2970
+ }
2971
+ .album-name {
2972
+ font-weight: 600;
2973
+ font-family: var(--font-display);
2974
+ font-size: 16.5px;
2975
+ }
2976
+ .album-count {
2977
+ margin-left: auto;
2978
+ font-size: 13px;
2979
+ color: var(--muted);
2980
+ }
2981
+ .album-tags {
2982
+ padding: 0 18px 16px;
2983
+ margin-top: -6px;
2984
+ display: flex;
2985
+ gap: 6px;
2986
+ }
2987
+ .album-tags .chip {
2988
+ font-size: 12px;
2989
+ padding: 1px 10px;
2990
+ }
2991
+ .album-sub {
2992
+ padding: 0 18px;
2993
+ margin-top: -8px;
2994
+ display: flex;
2995
+ flex-wrap: wrap;
2996
+ gap: 12px;
2997
+ font-size: 12.5px;
2998
+ color: var(--muted);
2999
+ }
3000
+ .album-cover-fallback {
3001
+ width: 100%;
3002
+ height: 100%;
3003
+ display: flex;
3004
+ align-items: center;
3005
+ justify-content: center;
3006
+ color: var(--muted);
3007
+ background: var(--bg-soft);
3008
+ }
3009
+ .album-cover-fallback svg {
3010
+ width: 34px;
3011
+ height: 34px;
3012
+ opacity: 0.55;
3013
+ }
3014
+
3015
+ /* 相册列表搜索(M3b-b8):与 modal input 同一套视觉 */
3016
+ .gallery-search {
3017
+ position: relative;
3018
+ margin-bottom: 16px;
3019
+ }
3020
+ .gallery-search svg {
3021
+ position: absolute;
3022
+ left: 13px;
3023
+ top: 50%;
3024
+ transform: translateY(-50%);
3025
+ width: 16px;
3026
+ height: 16px;
3027
+ color: var(--muted);
3028
+ pointer-events: none;
3029
+ }
3030
+ .gallery-search input {
3031
+ width: 100%;
3032
+ padding: 10px 14px 10px 38px;
3033
+ border-radius: var(--radius-sm);
3034
+ border: 1px solid var(--border-2);
3035
+ background: var(--bg);
3036
+ color: var(--ink);
3037
+ font-size: 14px;
3038
+ transition:
3039
+ border-color 0.15s,
3040
+ box-shadow 0.15s;
3041
+ }
3042
+ .gallery-search input:focus {
3043
+ outline: none;
3044
+ border-color: var(--accent);
3045
+ box-shadow: 0 0 0 3px var(--accent-soft);
3046
+ }
3047
+ .gallery-empty {
3048
+ padding: 48px 0;
3049
+ text-align: center;
3050
+ color: var(--muted);
3051
+ }
3052
+
3053
+ /* 相册详情页(M3b-b8):封面横幅 + 瀑布流 */
3054
+ .gallery-banner {
3055
+ position: relative;
3056
+ overflow: hidden;
3057
+ border-radius: var(--radius);
3058
+ aspect-ratio: 3 / 1;
3059
+ min-height: 200px;
3060
+ max-height: 360px;
3061
+ background: var(--bg-soft);
3062
+ }
3063
+ .gallery-banner > img {
3064
+ width: 100%;
3065
+ height: 100%;
3066
+ object-fit: cover;
3067
+ }
3068
+ .gallery-banner::after {
3069
+ content: "";
3070
+ position: absolute;
3071
+ inset: 0;
3072
+ background: linear-gradient(
3073
+ to top,
3074
+ rgba(0, 0, 0, 0.72),
3075
+ rgba(0, 0, 0, 0.28) 45%,
3076
+ rgba(0, 0, 0, 0.05)
3077
+ );
3078
+ }
3079
+ .gallery-back {
3080
+ position: absolute;
3081
+ top: 16px;
3082
+ left: 16px;
3083
+ z-index: 2;
3084
+ display: inline-flex;
3085
+ align-items: center;
3086
+ gap: 6px;
3087
+ padding: 6px 14px;
3088
+ border-radius: 999px;
3089
+ font-size: 13px;
3090
+ color: rgba(255, 255, 255, 0.92);
3091
+ background: rgba(0, 0, 0, 0.32);
3092
+ -webkit-backdrop-filter: blur(6px);
3093
+ backdrop-filter: blur(6px);
3094
+ transition: background-color 0.15s;
3095
+ }
3096
+ .gallery-back:hover {
3097
+ background: rgba(0, 0, 0, 0.52);
3098
+ color: #fff;
3099
+ }
3100
+ .gallery-back svg {
3101
+ width: 14px;
3102
+ height: 14px;
3103
+ }
3104
+ .gallery-banner-inner {
3105
+ position: absolute;
3106
+ left: 0;
3107
+ right: 0;
3108
+ bottom: 0;
3109
+ z-index: 1;
3110
+ padding: 22px 26px;
3111
+ color: #fff;
3112
+ }
3113
+ .gallery-title {
3114
+ font-family: var(--font-display);
3115
+ font-size: 24px;
3116
+ font-weight: 700;
3117
+ }
3118
+ .gallery-desc {
3119
+ margin-top: 6px;
3120
+ max-width: 640px;
3121
+ font-size: 14px;
3122
+ color: rgba(255, 255, 255, 0.78);
3123
+ }
3124
+ .gallery-meta {
3125
+ margin-top: 10px;
3126
+ display: flex;
3127
+ flex-wrap: wrap;
3128
+ align-items: center;
3129
+ gap: 16px;
3130
+ font-size: 13px;
3131
+ color: rgba(255, 255, 255, 0.82);
3132
+ }
3133
+ .gallery-meta svg {
3134
+ width: 14px;
3135
+ height: 14px;
3136
+ vertical-align: -2px;
3137
+ margin-right: 3px;
3138
+ }
3139
+ .gallery-meta .gallery-meta-tags {
3140
+ display: inline-flex;
3141
+ flex-wrap: wrap;
3142
+ gap: 6px;
3143
+ }
3144
+ .gallery-meta .gallery-meta-tags span {
3145
+ padding: 1px 10px;
3146
+ border-radius: 999px;
3147
+ font-size: 12px;
3148
+ background: rgba(255, 255, 255, 0.2);
3149
+ -webkit-backdrop-filter: blur(6px);
3150
+ backdrop-filter: blur(6px);
3151
+ }
3152
+ /* 无封面降级:卡式头部 */
3153
+ .gallery-head-plain {
3154
+ padding: 20px 24px;
3155
+ }
3156
+ .gallery-head-plain .gallery-title {
3157
+ color: var(--ink);
3158
+ }
3159
+ /* 降级头部 meta 位于浅色卡面:覆盖横幅白色系配色 */
3160
+ .gallery-head-plain .gallery-meta {
3161
+ color: var(--muted);
3162
+ }
3163
+ .gallery-head-plain .gallery-meta .gallery-meta-tags span {
3164
+ background: var(--bg-soft);
3165
+ color: var(--ink-2);
3166
+ -webkit-backdrop-filter: none;
3167
+ backdrop-filter: none;
3168
+ }
3169
+ /* 筛选容器 custom element:默认 inline,恢复块级 */
3170
+ gallery-filter {
3171
+ display: block;
3172
+ }
3173
+
3174
+ .gallery-masonry {
3175
+ column-count: 2;
3176
+ column-gap: 12px;
3177
+ }
3178
+ @media (min-width: 640px) {
3179
+ .gallery-masonry {
3180
+ column-width: var(--col-width, 240px);
3181
+ column-count: auto;
3182
+ }
3183
+ }
3184
+ .gallery-photo {
3185
+ position: relative;
3186
+ break-inside: avoid;
3187
+ margin: 0 0 12px;
3188
+ overflow: hidden;
3189
+ border-radius: var(--radius-sm);
3190
+ background: var(--bg-soft);
3191
+ cursor: zoom-in;
3192
+ }
3193
+ .gallery-photo img {
3194
+ display: block;
3195
+ width: 100%;
3196
+ height: auto;
3197
+ transition: transform 0.35s ease;
3198
+ }
3199
+ .gallery-photo:hover img {
3200
+ transform: scale(1.025);
3201
+ }
3202
+
3203
+ /* 灯箱(§4.69):样式由 photoswipe/photoswipe.css 提供(BaseLayout 引入) */
3204
+ /* 灯箱自定义 UI(§4.70/§4.71):全屏/自动播放按钮与缩略图条(可开关、内容居中)。
3205
+ 自定义图标用 .qy-pswp-icn 独立类名,避开 .pswp__icn 的 fill 覆盖(图标走 stroke 描边) */
3206
+ .qy-pswp-icn {
3207
+ position: absolute;
3208
+ inset: 0;
3209
+ margin: auto;
3210
+ width: 24px;
3211
+ height: 24px;
3212
+ stroke: var(--pswp-icon-color, #fff);
3213
+ fill: none;
3214
+ stroke-width: 1.6;
3215
+ stroke-linecap: round;
3216
+ stroke-linejoin: round;
3217
+ pointer-events: none;
3218
+ }
3219
+ .qy-icn-fill {
3220
+ fill: var(--pswp-icon-color, #fff);
3221
+ stroke: none;
3222
+ }
3223
+ .pswp__button--qy-fullscreen .qy-icn-fs-exit,
3224
+ .pswp__button--qy-slideshow .qy-icn-pause {
3225
+ display: none;
3226
+ }
3227
+ .pswp__button--qy-slideshow.is-active .qy-icn-play {
3228
+ display: none;
3229
+ }
3230
+ .pswp__button--qy-slideshow.is-active .qy-icn-pause {
3231
+ display: block;
3232
+ }
3233
+ .pswp:fullscreen .pswp__button--qy-fullscreen .qy-icn-fs-enter,
3234
+ .pswp:-webkit-full-screen .pswp__button--qy-fullscreen .qy-icn-fs-enter {
3235
+ display: none;
3236
+ }
3237
+ .pswp:fullscreen .pswp__button--qy-fullscreen .qy-icn-fs-exit,
3238
+ .pswp:-webkit-full-screen .pswp__button--qy-fullscreen .qy-icn-fs-exit {
3239
+ display: block;
3240
+ }
3241
+ .pswp__qy-thumbs {
3242
+ position: absolute;
3243
+ left: 0;
3244
+ right: 0;
3245
+ bottom: 0;
3246
+ z-index: 10;
3247
+ display: flex;
3248
+ gap: 8px;
3249
+ padding: 10px 12px;
3250
+ overflow-x: auto;
3251
+ background: linear-gradient(transparent, rgba(0, 0, 0, 0.4));
3252
+ -webkit-overflow-scrolling: touch;
3253
+ scrollbar-width: none;
3254
+ }
3255
+ .pswp__qy-thumbs::-webkit-scrollbar {
3256
+ display: none;
3257
+ }
3258
+ .pswp__qy-thumb {
3259
+ flex: 0 0 auto;
3260
+ width: 64px;
3261
+ height: 40px;
3262
+ padding: 0;
3263
+ border: 1px solid transparent;
3264
+ border-radius: 4px;
3265
+ overflow: hidden;
3266
+ opacity: 0.5;
3267
+ background: none;
3268
+ cursor: pointer;
3269
+ }
3270
+ .pswp__qy-thumb img {
3271
+ display: block;
3272
+ width: 100%;
3273
+ height: 100%;
3274
+ object-fit: cover;
3275
+ }
3276
+ .pswp__qy-thumb:hover {
3277
+ opacity: 0.85;
3278
+ }
3279
+ .pswp__qy-thumb.is-active {
3280
+ opacity: 1;
3281
+ border-color: var(--pswp-icon-color, #fff);
3282
+ }
3283
+ /* §4.71:缩略图条内容居中——首尾缩略图 margin auto 撑开空隙;图多溢出时 auto 归零,
3284
+ 自然退化为左对齐横向滚动,不会裁切左侧(flex 对齐安全技巧) */
3285
+ .pswp__qy-thumbs > .pswp__qy-thumb:first-child {
3286
+ margin-left: auto;
3287
+ }
3288
+ .pswp__qy-thumbs > .pswp__qy-thumb:last-child {
3289
+ margin-right: auto;
3290
+ }
3291
+ /* §4.71:开关按钮收起缩略图条 */
3292
+ .pswp__qy-thumbs.is-hidden {
3293
+ display: none;
3294
+ }
3295
+ @media (max-width: 639px) {
3296
+ .pswp__qy-thumbs {
3297
+ display: none;
3298
+ }
3299
+ }
3300
+
3301
+ /* modal(加密相册,M3b) */
3302
+ .modal {
3303
+ position: fixed;
3304
+ inset: 0;
3305
+ z-index: 320;
3306
+ display: flex;
3307
+ align-items: center;
3308
+ justify-content: center;
3309
+ background: rgba(12, 14, 15, 0.55);
3310
+ -webkit-backdrop-filter: blur(4px);
3311
+ backdrop-filter: blur(4px);
3312
+ opacity: 0;
3313
+ pointer-events: none;
3314
+ transition: opacity 0.2s;
3315
+ }
3316
+ .modal.open {
3317
+ opacity: 1;
3318
+ pointer-events: auto;
3319
+ }
3320
+ .modal-box {
3321
+ width: min(360px, calc(100vw - 48px));
3322
+ padding: 26px 26px 22px;
3323
+ background: var(--surface);
3324
+ border: 1px solid var(--border);
3325
+ border-radius: var(--radius);
3326
+ box-shadow: var(--shadow-md);
3327
+ }
3328
+ .modal-box h3 {
3329
+ font-family: var(--font-display);
3330
+ font-size: 18px;
3331
+ margin-bottom: 6px;
3332
+ }
3333
+ .modal-box .modal-hint {
3334
+ font-size: 13.5px;
3335
+ color: var(--muted);
3336
+ margin-bottom: 16px;
3337
+ }
3338
+ .modal-box input {
3339
+ width: 100%;
3340
+ padding: 10px 14px;
3341
+ border-radius: var(--radius-sm);
3342
+ border: 1px solid var(--border-2);
3343
+ background: var(--bg);
3344
+ color: var(--ink);
3345
+ }
3346
+ .modal-box input:focus {
3347
+ outline: none;
3348
+ border-color: var(--accent);
3349
+ box-shadow: 0 0 0 3px var(--accent-soft);
3350
+ }
3351
+ .modal-actions {
3352
+ margin-top: 16px;
3353
+ display: flex;
3354
+ justify-content: flex-end;
3355
+ gap: 10px;
3356
+ }
3357
+ .modal-error {
3358
+ margin-top: 10px;
3359
+ font-size: 13px;
3360
+ color: #c0564f;
3361
+ min-height: 1.3em;
3362
+ }
3363
+ .modal-box.shake {
3364
+ animation: shake 0.4s;
3365
+ }
3366
+ @keyframes shake {
3367
+ 0%,
3368
+ 100% {
3369
+ transform: translateX(0);
3370
+ }
3371
+ 25% {
3372
+ transform: translateX(-7px);
3373
+ }
3374
+ 50% {
3375
+ transform: translateX(6px);
3376
+ }
3377
+ 75% {
3378
+ transform: translateX(-4px);
3379
+ }
3380
+ }
3381
+
3382
+ /* ---------- 10. 友链 ---------- */
3383
+ .friend-grid {
3384
+ display: grid;
3385
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
3386
+ gap: 20px;
3387
+ }
3388
+ .friend-card {
3389
+ display: flex;
3390
+ gap: 16px;
3391
+ align-items: center;
3392
+ padding: 20px 22px;
3393
+ color: var(--ink);
3394
+ transition:
3395
+ box-shadow 0.2s,
3396
+ transform 0.2s,
3397
+ border-color 0.2s;
3398
+ }
3399
+ .friend-card:hover {
3400
+ box-shadow: var(--shadow-md);
3401
+ transform: translateY(-2px);
3402
+ border-color: var(--border-2);
3403
+ color: var(--ink);
3404
+ }
3405
+ .friend-avatar {
3406
+ flex: none;
3407
+ width: 56px;
3408
+ height: 56px;
3409
+ border-radius: 50%;
3410
+ overflow: hidden;
3411
+ border: 1px solid var(--border);
3412
+ }
3413
+ .friend-avatar img {
3414
+ width: 100%;
3415
+ height: 100%;
3416
+ object-fit: cover;
3417
+ }
3418
+ .friend-name {
3419
+ font-weight: 700;
3420
+ font-size: 16px;
3421
+ font-family: var(--font-display);
3422
+ }
3423
+ .friend-card:hover .friend-name {
3424
+ color: var(--accent-deep);
3425
+ }
3426
+ html.dark .friend-card:hover .friend-name {
3427
+ color: var(--accent);
3428
+ }
3429
+ .friend-desc {
3430
+ margin-top: 3px;
3431
+ font-size: 13.5px;
3432
+ color: var(--muted);
3433
+ line-height: 1.6;
3434
+ }
3435
+ .friend-apply {
3436
+ margin-top: 20px;
3437
+ padding: 24px 26px;
3438
+ display: flex;
3439
+ align-items: center;
3440
+ justify-content: space-between;
3441
+ gap: 18px;
3442
+ flex-wrap: wrap;
3443
+ }
3444
+ .friend-apply .fa-title {
3445
+ font-family: var(--font-display);
3446
+ font-weight: 700;
3447
+ font-size: 17px;
3448
+ }
3449
+ .friend-apply .fa-desc {
3450
+ margin-top: 4px;
3451
+ font-size: 14px;
3452
+ color: var(--muted);
3453
+ }
3454
+ .friend-tags {
3455
+ margin-top: 7px;
3456
+ display: flex;
3457
+ flex-wrap: wrap;
3458
+ gap: 4px;
3459
+ }
3460
+ .friend-tags .chip {
3461
+ font-size: 11px;
3462
+ padding: 1px 9px;
3463
+ }
3464
+
3465
+ /* ---------- 10.1 字头像兜底(友链/打赏名单无图时) ---------- */
3466
+ .avatar-fallback {
3467
+ display: inline-flex;
3468
+ align-items: center;
3469
+ justify-content: center;
3470
+ background: var(--accent-soft);
3471
+ color: var(--accent-ink);
3472
+ font-weight: 700;
3473
+ user-select: none;
3474
+ }
3475
+ .friend-avatar .avatar-fallback {
3476
+ width: 100%;
3477
+ height: 100%;
3478
+ font-size: 20px;
3479
+ font-family: var(--font-display);
3480
+ }
3481
+ .side-friends .avatar-fallback {
3482
+ width: 24px;
3483
+ height: 24px;
3484
+ font-size: 12px;
3485
+ border-radius: 50%;
3486
+ border: 1px solid var(--border);
3487
+ flex: none;
3488
+ }
3489
+ .sponsor-item-avatar.avatar-fallback {
3490
+ border-radius: 50%;
3491
+ font-size: 14px;
3492
+ }
3493
+
3494
+ /* ---------- 10.2 独立页(关于/留言板)正文卡 ---------- */
3495
+ .page-card {
3496
+ margin-top: 26px;
3497
+ padding: 26px 30px;
3498
+ }
3499
+ .page-card .prose > :first-child,
3500
+ .prose.page-card > :first-child {
3501
+ margin-top: 0;
3502
+ }
3503
+ .comment-placeholder {
3504
+ text-align: center;
3505
+ color: var(--muted);
3506
+ font-size: 14px;
3507
+ }
3508
+ .comment-placeholder p {
3509
+ margin: 8px 0;
3510
+ }
3511
+
3512
+ /* ---------- 10.3 打赏页 ---------- */
3513
+ .sponsor-usage {
3514
+ margin-top: 26px;
3515
+ padding: 14px 18px;
3516
+ font-size: 14px;
3517
+ color: var(--ink-2);
3518
+ line-height: 1.7;
3519
+ background: var(--accent-soft);
3520
+ border: 1px solid hsl(var(--accent-h) 30% 60% / 0.45);
3521
+ }
3522
+ .sponsor-grid {
3523
+ margin-top: 26px;
3524
+ display: grid;
3525
+ grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
3526
+ gap: 20px;
3527
+ }
3528
+ .sponsor-method {
3529
+ display: flex;
3530
+ flex-direction: column;
3531
+ align-items: center;
3532
+ gap: 12px;
3533
+ padding: 26px 22px;
3534
+ text-align: center;
3535
+ }
3536
+ .sponsor-method .sm-name {
3537
+ font-family: var(--font-display);
3538
+ font-weight: 700;
3539
+ font-size: 17px;
3540
+ display: flex;
3541
+ align-items: center;
3542
+ gap: 8px;
3543
+ }
3544
+ .sponsor-method .sm-icon {
3545
+ font-size: 20px;
3546
+ }
3547
+ .sponsor-method .sm-desc {
3548
+ margin: 0;
3549
+ font-size: 13.5px;
3550
+ color: var(--muted);
3551
+ }
3552
+ .sponsor-qr {
3553
+ width: 180px;
3554
+ height: 180px;
3555
+ padding: 12px;
3556
+ background: #fff;
3557
+ border: 1px solid var(--border);
3558
+ border-radius: 12px;
3559
+ object-fit: contain;
3560
+ }
3561
+ .sponsor-qr-empty {
3562
+ display: flex;
3563
+ align-items: center;
3564
+ justify-content: center;
3565
+ color: var(--muted);
3566
+ font-size: 13px;
3567
+ }
3568
+ .sponsor-method .sm-link {
3569
+ margin-top: auto;
3570
+ }
3571
+ .sponsor-list-title {
3572
+ font-family: var(--font-display);
3573
+ font-size: 17px;
3574
+ font-weight: 700;
3575
+ margin: 0 0 14px;
3576
+ }
3577
+ .sponsor-list-title .sl-count {
3578
+ margin-left: 8px;
3579
+ font-size: 12px;
3580
+ color: var(--muted);
3581
+ font-variant-numeric: tabular-nums;
3582
+ font-weight: 400;
3583
+ }
3584
+ .sponsor-list {
3585
+ display: grid;
3586
+ gap: 10px;
3587
+ }
3588
+ .sponsor-item {
3589
+ display: flex;
3590
+ align-items: center;
3591
+ gap: 12px;
3592
+ padding: 10px 14px;
3593
+ border: 1px solid var(--border);
3594
+ border-radius: 14px;
3595
+ }
3596
+ .sponsor-item-avatar {
3597
+ flex: none;
3598
+ width: 36px;
3599
+ height: 36px;
3600
+ border-radius: 50%;
3601
+ object-fit: cover;
3602
+ border: 1px solid var(--border);
3603
+ }
3604
+ .sponsor-item-name {
3605
+ font-size: 14px;
3606
+ font-weight: 600;
3607
+ display: flex;
3608
+ align-items: baseline;
3609
+ gap: 8px;
3610
+ flex-wrap: wrap;
3611
+ }
3612
+ .sponsor-item-name .sl-amount {
3613
+ color: var(--accent-ink);
3614
+ font-size: 13px;
3615
+ }
3616
+ .sponsor-item-date {
3617
+ font-size: 12.5px;
3618
+ color: var(--muted);
3619
+ }
3620
+
3621
+ /* ---------- 11. Footer ---------- */
3622
+ .site-footer {
3623
+ border-top: 1px solid var(--border);
3624
+ background: var(--bg-soft);
3625
+ }
3626
+ .footer-inner {
3627
+ padding: 36px 24px 40px;
3628
+ text-align: center;
3629
+ }
3630
+ /* §4.57 行距统一收口:任意行(含自定义行)相邻间距恒定,customHtml 缺省时无多余上边距 */
3631
+ .footer-inner > * + * {
3632
+ margin-top: 6px;
3633
+ }
3634
+ .footer-line {
3635
+ font-size: 14px;
3636
+ color: var(--ink-2);
3637
+ }
3638
+ /* §4.57 页脚链接(RSS/Sitemap/Powered by/自定义行)统一 accent 风格,hover 才出下划线 */
3639
+ .footer-line a,
3640
+ .footer-sub a,
3641
+ .footer-custom a {
3642
+ color: var(--accent);
3643
+ text-decoration: none;
3644
+ }
3645
+ .footer-line a:hover,
3646
+ .footer-sub a:hover,
3647
+ .footer-custom a:hover {
3648
+ text-decoration: underline;
3649
+ text-underline-offset: 2px;
3650
+ }
3651
+ .footer-sep {
3652
+ margin: 0 6px;
3653
+ color: var(--muted);
3654
+ }
3655
+ .footer-sub {
3656
+ font-size: 12.5px;
3657
+ color: var(--muted);
3658
+ }
3659
+ /* §4.57 自定义行(备案号/统计等多段内容):flex 换行居中,与相邻行同字号同色 */
3660
+ .footer-custom {
3661
+ display: flex;
3662
+ flex-wrap: wrap;
3663
+ justify-content: center;
3664
+ gap: 2px 16px;
3665
+ font-size: 12.5px;
3666
+ color: var(--muted);
3667
+ }
3668
+
3669
+ /* ---------- 12. 搜索浮层(M3b Pagefind 启用) ---------- */
3670
+ .search-overlay {
3671
+ position: fixed;
3672
+ inset: 0;
3673
+ z-index: 250;
3674
+ background: rgba(12, 14, 15, 0.45);
3675
+ -webkit-backdrop-filter: blur(6px);
3676
+ backdrop-filter: blur(6px);
3677
+ display: flex;
3678
+ justify-content: center;
3679
+ align-items: flex-start;
3680
+ padding: 12vh 20px 0;
3681
+ }
3682
+ .search-overlay[hidden] {
3683
+ display: none !important;
3684
+ }
3685
+ .search-panel {
3686
+ width: min(560px, 100%);
3687
+ background: var(--surface);
3688
+ border: 1px solid var(--border);
3689
+ border-radius: var(--radius);
3690
+ box-shadow: var(--shadow-md);
3691
+ overflow: hidden;
3692
+ }
3693
+ .search-box {
3694
+ display: flex;
3695
+ align-items: center;
3696
+ gap: 10px;
3697
+ padding: 14px 16px;
3698
+ border-bottom: 1px solid var(--border);
3699
+ }
3700
+ .search-box > svg {
3701
+ flex: none;
3702
+ width: 18px;
3703
+ height: 18px;
3704
+ color: var(--muted);
3705
+ }
3706
+ .search-box input {
3707
+ flex: 1;
3708
+ border: none;
3709
+ background: transparent;
3710
+ outline: none;
3711
+ font-size: 16px;
3712
+ color: var(--ink);
3713
+ }
3714
+ .search-box input::placeholder {
3715
+ color: var(--muted);
3716
+ }
3717
+ .search-results {
3718
+ max-height: 320px;
3719
+ overflow-y: auto;
3720
+ padding: 8px;
3721
+ }
3722
+ .search-item {
3723
+ display: block;
3724
+ width: 100%;
3725
+ text-align: left;
3726
+ padding: 10px 14px;
3727
+ border-radius: var(--radius-sm);
3728
+ }
3729
+ .search-item .si-title {
3730
+ font-size: 14.5px;
3731
+ font-weight: 600;
3732
+ color: var(--ink);
3733
+ }
3734
+ .search-item .si-meta {
3735
+ margin-top: 2px;
3736
+ font-size: 12.5px;
3737
+ color: var(--muted);
3738
+ }
3739
+ .search-item.is-active,
3740
+ .search-item:hover {
3741
+ background: var(--accent-soft);
3742
+ }
3743
+ .search-item.is-active .si-title {
3744
+ color: var(--accent-ink);
3745
+ }
3746
+ .search-empty {
3747
+ padding: 34px 0;
3748
+ text-align: center;
3749
+ color: var(--muted);
3750
+ font-size: 14px;
3751
+ }
3752
+ .search-hint {
3753
+ padding: 10px 16px;
3754
+ font-size: 12px;
3755
+ color: var(--muted);
3756
+ border-top: 1px solid var(--border);
3757
+ background: var(--bg-soft);
3758
+ }
3759
+
3760
+ /* ---------- 13. back-top ---------- */
3761
+ /* 阅读进度条(§4.12):fixed 顶边 3px,scaleX 驱动零重排;层级盖过 header(100)、让位 skip-link(200) */
3762
+ .read-progress {
3763
+ position: fixed;
3764
+ top: 0;
3765
+ left: 0;
3766
+ z-index: 150;
3767
+ width: 100%;
3768
+ height: 3px;
3769
+ transform-origin: 0 50%;
3770
+ transform: scaleX(0);
3771
+ background: linear-gradient(
3772
+ 90deg,
3773
+ var(--accent),
3774
+ var(--accent-deep, var(--accent))
3775
+ );
3776
+ pointer-events: none;
3777
+ }
3778
+ .back-top {
3779
+ position: fixed;
3780
+ right: 26px;
3781
+ bottom: 30px;
3782
+ z-index: 90;
3783
+ width: 42px;
3784
+ height: 42px;
3785
+ border-radius: 50%;
3786
+ display: flex;
3787
+ align-items: center;
3788
+ justify-content: center;
3789
+ background: var(--surface);
3790
+ color: var(--ink-2);
3791
+ border: 1px solid var(--border);
3792
+ box-shadow: var(--shadow-sm);
3793
+ transition:
3794
+ color 0.15s,
3795
+ border-color 0.15s,
3796
+ transform 0.15s;
3797
+ }
3798
+ .back-top:hover {
3799
+ color: var(--accent-ink);
3800
+ border-color: var(--accent);
3801
+ transform: translateY(-2px);
3802
+ }
3803
+ .back-top svg {
3804
+ width: 20px;
3805
+ height: 20px;
3806
+ }
3807
+
3808
+ /* ---------- 14. 响应式 ---------- */
3809
+ @media (max-width: 860px) {
3810
+ .site-nav {
3811
+ position: absolute;
3812
+ top: var(--header-h);
3813
+ left: 0;
3814
+ right: 0;
3815
+ flex-direction: column;
3816
+ align-items: stretch;
3817
+ gap: 2px;
3818
+ margin: 0;
3819
+ padding: 10px 16px 14px;
3820
+ background: var(--surface);
3821
+ border-bottom: 1px solid var(--border);
3822
+ box-shadow: var(--shadow-md);
3823
+ display: none;
3824
+ }
3825
+ .site-nav.open {
3826
+ display: flex;
3827
+ }
3828
+ .nav-link {
3829
+ padding: 10px 14px;
3830
+ border-radius: var(--radius-sm);
3831
+ }
3832
+ .nav-burger {
3833
+ display: inline-flex;
3834
+ }
3835
+ }
3836
+ @media (max-width: 640px) {
3837
+ /* 小屏留白收紧(§4.13):24px 留白在窄屏占比过大 */
3838
+ .shell {
3839
+ padding-inline: 16px;
3840
+ }
3841
+ .post-body {
3842
+ padding: 18px 18px 20px;
3843
+ }
3844
+ .post-card.no-cover:not(.compact) .post-body {
3845
+ padding-right: 72px;
3846
+ }
3847
+ .side-card {
3848
+ /* §4.46 移动端与桌面统一 16px 内边距 */
3849
+ padding: 16px;
3850
+ }
3851
+ .site-main {
3852
+ padding-top: 24px;
3853
+ }
3854
+ .hero {
3855
+ padding: 12px 0 28px;
3856
+ }
3857
+ .post-card.featured {
3858
+ grid-template-columns: 1fr;
3859
+ }
3860
+ .post-card.featured .post-cover {
3861
+ aspect-ratio: 16 / 9;
3862
+ min-height: 0;
3863
+ }
3864
+ .post-card.compact {
3865
+ grid-template-columns: 96px 1fr;
3866
+ }
3867
+ .post-nav {
3868
+ grid-template-columns: 1fr;
3869
+ }
3870
+ .post-nav .next {
3871
+ text-align: left;
3872
+ }
3873
+ .home-layout {
3874
+ gap: 24px;
3875
+ }
3876
+ .back-top {
3877
+ right: 16px;
3878
+ bottom: 20px;
3879
+ }
3880
+ /* 搜索移动端形态(§4.56):内联框退化为 icon 按钮,浮层内含输入框 */
3881
+ .nav-search {
3882
+ display: none;
3883
+ }
3884
+ .nav-search-toggle {
3885
+ display: inline-flex;
3886
+ }
3887
+ .search-bar {
3888
+ display: flex;
3889
+ }
3890
+ /* 搜索浮层移动端:fixed 贴边铺开 */
3891
+ .search-pop {
3892
+ position: fixed;
3893
+ left: 12px;
3894
+ right: 12px;
3895
+ top: calc(var(--header-h) + 8px);
3896
+ width: auto;
3897
+ }
3898
+ }
3899
+
3900
+ /* ---------- 15. 动效偏好 ---------- */
3901
+ @media (prefers-reduced-motion: reduce) {
3902
+ html {
3903
+ scroll-behavior: auto;
3904
+ }
3905
+ *,
3906
+ *::before,
3907
+ *::after {
3908
+ animation-duration: 0.01ms !important;
3909
+ transition-duration: 0.01ms !important;
3910
+ }
3911
+ .reveal {
3912
+ opacity: 1;
3913
+ transform: none;
3914
+ }
3915
+ }
3916
+
3917
+ /* ---------- 16. 图表与公式 / 邮箱防爬(M3b-b4) ---------- */
3918
+ .diagram-container {
3919
+ position: relative;
3920
+ margin: 24px 0;
3921
+ padding: 4px;
3922
+ overflow: hidden;
3923
+ border: 1px solid var(--border);
3924
+ border-radius: var(--radius);
3925
+ background: var(--surface);
3926
+ /* 触摸设备:垂直滚动留给页面,捏合交给全屏层 */
3927
+ touch-action: pan-y;
3928
+ }
3929
+ .diagram-wrapper {
3930
+ text-align: center;
3931
+ }
3932
+ .mermaid-svg-light svg,
3933
+ .mermaid-svg-dark svg,
3934
+ .plantuml-image {
3935
+ max-width: 100%;
3936
+ height: auto;
3937
+ margin: 0 auto;
3938
+ }
3939
+ /* Mermaid 构建期双主题:同一份图渲染两份 SVG,按暗色模式显隐 */
3940
+ .mermaid-svg-dark {
3941
+ display: none;
3942
+ }
3943
+ html.dark .mermaid-svg-light {
3944
+ display: none;
3945
+ }
3946
+ html.dark .mermaid-svg-dark {
3947
+ display: block;
3948
+ }
3949
+
3950
+ /* Mermaid 渲染失败降级:提示 + 源码 */
3951
+ .mermaid-error {
3952
+ padding: 14px 16px;
3953
+ text-align: left;
3954
+ }
3955
+ .mermaid-error p,
3956
+ .plantuml-error p {
3957
+ font-size: 0.9em;
3958
+ color: var(--muted);
3959
+ }
3960
+ .mermaid-error .mermaid-fallback-code {
3961
+ margin: 10px 0 0;
3962
+ padding: 14px;
3963
+ font-family: var(--font-mono);
3964
+ font-size: 0.85em;
3965
+ line-height: 1.6;
3966
+ overflow-x: auto;
3967
+ white-space: pre-wrap;
3968
+ word-break: break-word;
3969
+ background: var(--bg-soft);
3970
+ border-radius: var(--radius-sm);
3971
+ }
3972
+
3973
+ /* PlantUML 加载失败:提示 + 重试 */
3974
+ .plantuml-error {
3975
+ padding: 2px 0 10px;
3976
+ text-align: center;
3977
+ }
3978
+ .plantuml-error button {
3979
+ margin-top: 8px;
3980
+ padding: 4px 14px;
3981
+ border: 1px solid var(--border-2);
3982
+ border-radius: var(--radius-sm);
3983
+ background: var(--surface);
3984
+ color: var(--ink-2);
3985
+ font-size: 0.85em;
3986
+ cursor: pointer;
3987
+ }
3988
+ .plantuml-error button:hover {
3989
+ color: var(--ink);
3990
+ border-color: var(--muted);
3991
+ }
3992
+
3993
+ /* pan-zoom 控制栏:悬停浮出,触屏常显 */
3994
+ .diagram-controls {
3995
+ position: absolute;
3996
+ top: 8px;
3997
+ right: 8px;
3998
+ z-index: 2;
3999
+ display: flex;
4000
+ gap: 2px;
4001
+ padding: 3px;
4002
+ background: hsl(0 0% 100% / 0.85);
4003
+ backdrop-filter: blur(4px);
4004
+ border: 1px solid var(--border);
4005
+ border-radius: var(--radius-sm);
4006
+ box-shadow: var(--shadow-sm);
4007
+ opacity: 0;
4008
+ transition: opacity 0.18s ease;
4009
+ }
4010
+ html.dark .diagram-controls {
4011
+ background: hsl(0 0% 8% / 0.85);
4012
+ }
4013
+ .diagram-container:hover .diagram-controls,
4014
+ .diagram-container:focus-within .diagram-controls {
4015
+ opacity: 1;
4016
+ }
4017
+ .diagram-ctrl-btn {
4018
+ width: 26px;
4019
+ height: 26px;
4020
+ display: inline-flex;
4021
+ align-items: center;
4022
+ justify-content: center;
4023
+ border: none;
4024
+ border-radius: 6px;
4025
+ background: transparent;
4026
+ color: var(--ink-2);
4027
+ font-size: 14px;
4028
+ line-height: 1;
4029
+ cursor: pointer;
4030
+ }
4031
+ .diagram-ctrl-btn:hover {
4032
+ background: var(--bg-soft);
4033
+ color: var(--ink);
4034
+ }
4035
+
4036
+ /* 全屏查看层 */
4037
+ .diagram-fullscreen-overlay {
4038
+ position: fixed;
4039
+ inset: 0;
4040
+ z-index: 999;
4041
+ display: flex;
4042
+ align-items: center;
4043
+ justify-content: center;
4044
+ background: hsl(0 0% 0% / 0.8);
4045
+ backdrop-filter: blur(3px);
4046
+ }
4047
+ .diagram-fs-content {
4048
+ width: 94vw;
4049
+ height: 86vh;
4050
+ display: flex;
4051
+ align-items: center;
4052
+ justify-content: center;
4053
+ overflow: hidden;
4054
+ cursor: grab;
4055
+ }
4056
+ .diagram-fs-content svg,
4057
+ .diagram-fs-content img {
4058
+ max-width: 100%;
4059
+ max-height: 100%;
4060
+ }
4061
+ .diagram-fs-controls {
4062
+ position: absolute;
4063
+ top: 18px;
4064
+ right: 18px;
4065
+ display: flex;
4066
+ gap: 4px;
4067
+ padding: 4px;
4068
+ background: hsl(0 0% 100% / 0.92);
4069
+ border-radius: var(--radius-sm);
4070
+ box-shadow: var(--shadow-md);
4071
+ }
4072
+ html.dark .diagram-fs-controls {
4073
+ background: hsl(0 0% 12% / 0.92);
4074
+ }
4075
+ .diagram-fs-controls .diagram-ctrl-btn {
4076
+ width: 30px;
4077
+ height: 30px;
4078
+ font-size: 16px;
4079
+ }
4080
+
4081
+ /* KaTeX:宽公式横向滚动而非撑破版心 */
4082
+ .katex-display {
4083
+ overflow-x: auto;
4084
+ overflow-y: hidden;
4085
+ padding: 4px 0;
4086
+ }
4087
+ /* math 块(§4.61 起):rehype-katex 先于 EC 执行,产物直接落入 .prose,
4088
+ KaTeX 取 currentColor 随 .prose 的 var(--ink) 自动适配双主题 */
4089
+
4090
+ /* 邮箱防爬:href 已置 '#',保持可点击的视觉暗示 */
4091
+ a[data-encoded-email] {
4092
+ cursor: pointer;
4093
+ }
4094
+
4095
+ /* 加密文章(M3b-b7):锁卡 + 解密容器 + meta 锁标 */
4096
+ .enc-flag {
4097
+ color: var(--accent);
4098
+ }
4099
+ .enc-box {
4100
+ display: flex;
4101
+ justify-content: center;
4102
+ padding: 3rem 1rem;
4103
+ }
4104
+ .enc-card {
4105
+ display: flex;
4106
+ flex-direction: column;
4107
+ align-items: center;
4108
+ gap: 10px;
4109
+ width: 100%;
4110
+ max-width: 360px;
4111
+ padding: 2rem 1.5rem;
4112
+ background: var(--surface);
4113
+ border: 1px solid var(--border);
4114
+ border-radius: var(--radius);
4115
+ box-shadow: var(--shadow-sm);
4116
+ text-align: center;
4117
+ }
4118
+ .enc-icon {
4119
+ width: 44px;
4120
+ height: 44px;
4121
+ color: var(--accent);
4122
+ }
4123
+ .enc-title {
4124
+ margin: 0;
4125
+ font-family: var(--font-display);
4126
+ font-size: 1.05rem;
4127
+ font-weight: 700;
4128
+ }
4129
+ .enc-desc {
4130
+ margin: 0;
4131
+ font-size: 0.85rem;
4132
+ color: var(--ink-2);
4133
+ }
4134
+ .enc-hint {
4135
+ margin: 0;
4136
+ font-size: 0.78rem;
4137
+ color: var(--muted);
4138
+ }
4139
+ .enc-form {
4140
+ display: flex;
4141
+ flex-direction: column;
4142
+ gap: 10px;
4143
+ width: 100%;
4144
+ margin-top: 6px;
4145
+ }
4146
+ .enc-form input {
4147
+ width: 100%;
4148
+ padding: 9px 12px;
4149
+ font-size: 0.9rem;
4150
+ color: var(--ink);
4151
+ background: var(--bg);
4152
+ border: 1px solid var(--border);
4153
+ border-radius: var(--radius-sm);
4154
+ outline: none;
4155
+ transition: border-color 0.15s ease;
4156
+ }
4157
+ .enc-form input:focus {
4158
+ border-color: var(--accent);
4159
+ }
4160
+ .enc-form button {
4161
+ padding: 9px 12px;
4162
+ font-size: 0.9rem;
4163
+ font-weight: 500;
4164
+ cursor: pointer;
4165
+ color: #fff;
4166
+ background: var(--accent);
4167
+ border: none;
4168
+ border-radius: var(--radius-sm);
4169
+ transition:
4170
+ filter 0.15s ease,
4171
+ transform 0.1s ease;
4172
+ }
4173
+ .enc-form button:hover {
4174
+ filter: brightness(1.06);
4175
+ }
4176
+ .enc-form button:active {
4177
+ transform: scale(0.98);
4178
+ }
4179
+ .enc-error {
4180
+ margin: 0;
4181
+ font-size: 0.78rem;
4182
+ color: #d4574e;
4183
+ }
4184
+
4185
+ @media (max-width: 640px) {
4186
+ /* 触屏无 hover:图表控制栏常显 */
4187
+ .diagram-controls {
4188
+ opacity: 1;
4189
+ }
4190
+ }
4191
+
4192
+ /* ---------- 17. 相关/随机文章推荐(M3b-b9) ---------- */
4193
+ .related-grid {
4194
+ display: grid;
4195
+ /* minmax(0,1fr) 防止轨道被 nowrap 标题的 min-content 撑破页面 */
4196
+ grid-template-columns: repeat(2, minmax(0, 1fr));
4197
+ gap: 16px;
4198
+ margin: 28px 0;
4199
+ }
4200
+ .related-card {
4201
+ display: flex;
4202
+ flex-direction: column;
4203
+ /* 同原版 card-base:min-width:0 + overflow:hidden 保证截断链生效 */
4204
+ min-width: 0;
4205
+ overflow: hidden;
4206
+ padding: 18px 20px;
4207
+ background: var(--surface);
4208
+ border: 1px solid var(--border);
4209
+ border-radius: var(--radius);
4210
+ box-shadow: var(--shadow-sm);
4211
+ }
4212
+ .related-head {
4213
+ display: flex;
4214
+ align-items: center;
4215
+ gap: 8px;
4216
+ padding-bottom: 12px;
4217
+ margin-bottom: 6px;
4218
+ font-family: var(--font-display);
4219
+ font-size: 0.95rem;
4220
+ font-weight: 700;
4221
+ border-bottom: 1px dashed var(--border);
4222
+ }
4223
+ .related-head svg {
4224
+ width: 18px;
4225
+ height: 18px;
4226
+ flex-shrink: 0;
4227
+ color: var(--accent);
4228
+ }
4229
+ .related-badge {
4230
+ margin-left: auto;
4231
+ padding: 2px 8px;
4232
+ font-size: 0.68rem;
4233
+ font-weight: 500;
4234
+ letter-spacing: 0.02em;
4235
+ color: var(--accent-ink);
4236
+ background: var(--accent-soft);
4237
+ border-radius: 999px;
4238
+ }
4239
+ .related-list {
4240
+ display: flex;
4241
+ flex-direction: column;
4242
+ flex: 1;
4243
+ }
4244
+ .related-item {
4245
+ display: flex;
4246
+ align-items: center;
4247
+ gap: 10px;
4248
+ padding: 10px 8px;
4249
+ margin: 0 -8px;
4250
+ border-radius: var(--radius-sm);
4251
+ transition: background-color 0.15s ease;
4252
+ }
4253
+ .related-item + .related-item {
4254
+ border-top: 1px dashed var(--border);
4255
+ }
4256
+ .related-item:hover {
4257
+ background: var(--bg-soft);
4258
+ }
4259
+ .related-num {
4260
+ display: inline-flex;
4261
+ align-items: center;
4262
+ justify-content: center;
4263
+ width: 24px;
4264
+ height: 24px;
4265
+ flex-shrink: 0;
4266
+ font-size: 0.75rem;
4267
+ font-weight: 700;
4268
+ color: var(--accent-ink);
4269
+ background: var(--accent-soft);
4270
+ border-radius: var(--radius-sm);
4271
+ }
4272
+ .related-body {
4273
+ display: flex;
4274
+ flex-direction: column;
4275
+ gap: 3px;
4276
+ flex: 1;
4277
+ min-width: 0;
4278
+ }
4279
+ .related-title {
4280
+ font-size: 0.875rem;
4281
+ font-weight: 700;
4282
+ color: var(--ink);
4283
+ white-space: nowrap;
4284
+ overflow: hidden;
4285
+ text-overflow: ellipsis;
4286
+ transition: color 0.15s ease;
4287
+ }
4288
+ .related-item:hover .related-title {
4289
+ color: var(--accent-ink);
4290
+ }
4291
+ .related-meta {
4292
+ display: flex;
4293
+ align-items: center;
4294
+ gap: 8px;
4295
+ min-width: 0;
4296
+ font-size: 0.75rem;
4297
+ color: var(--muted);
4298
+ }
4299
+ .related-cat {
4300
+ flex-shrink: 0;
4301
+ padding: 1px 7px;
4302
+ font-size: 0.68rem;
4303
+ color: var(--ink-2);
4304
+ background: var(--bg-soft);
4305
+ border-radius: 999px;
4306
+ }
4307
+ .related-desc {
4308
+ white-space: nowrap;
4309
+ overflow: hidden;
4310
+ text-overflow: ellipsis;
4311
+ }
4312
+ .related-arrow {
4313
+ width: 18px;
4314
+ height: 18px;
4315
+ flex-shrink: 0;
4316
+ color: var(--muted);
4317
+ transition:
4318
+ color 0.15s ease,
4319
+ transform 0.15s ease;
4320
+ }
4321
+ .related-item:hover .related-arrow {
4322
+ color: var(--accent);
4323
+ transform: translateX(2px);
4324
+ }
4325
+ .related-empty {
4326
+ display: flex;
4327
+ flex-direction: column;
4328
+ align-items: center;
4329
+ justify-content: center;
4330
+ gap: 8px;
4331
+ flex: 1;
4332
+ min-height: 140px;
4333
+ font-size: 0.85rem;
4334
+ color: var(--muted);
4335
+ }
4336
+ .related-empty svg {
4337
+ width: 32px;
4338
+ height: 32px;
4339
+ opacity: 0.5;
4340
+ }
4341
+
4342
+ @media (max-width: 860px) {
4343
+ .related-grid {
4344
+ grid-template-columns: 1fr;
4345
+ }
4346
+ }
4347
+
4348
+ /* ---------- 18. LQIP 占位渐变(M3b-b9) ---------- */
4349
+ /* 占位层绝对定位盖在 img 上(z-index 低于各容器内徽标/文案 z-index 1/2);
4350
+ 图片在下方正常加载,加载完成后容器加 .qy-img-in 驱动占位淡出。
4351
+ 不给 img 加 opacity/transition,避免覆盖 .post-cover img 的 hover 缩放过渡 */
4352
+ .qy-lqip {
4353
+ position: absolute;
4354
+ inset: 0;
4355
+ z-index: 0;
4356
+ pointer-events: none;
4357
+ transition: opacity 0.6s ease;
4358
+ }
4359
+ .qy-img-in > .qy-lqip {
4360
+ opacity: 0;
4361
+ }
4362
+ @media (prefers-reduced-motion: reduce) {
4363
+ .qy-lqip {
4364
+ transition: none;
4365
+ }
4366
+ }
4367
+
4368
+ /* ---------- 19. 分享海报(M3b-b9) ---------- */
4369
+ /* 文章页支持卡(打赏 + 分享海报入口) */
4370
+ .support-card {
4371
+ margin-top: 28px;
4372
+ display: flex;
4373
+ align-items: center;
4374
+ justify-content: space-between;
4375
+ gap: 18px;
4376
+ padding: 18px 22px;
4377
+ border: 1px dashed var(--border);
4378
+ border-radius: 14px;
4379
+ background: var(--surface);
4380
+ }
4381
+ .support-info h3 {
4382
+ margin: 0;
4383
+ font-size: 1rem;
4384
+ color: var(--ink);
4385
+ }
4386
+ .support-info p {
4387
+ margin: 4px 0 0;
4388
+ font-size: 0.85rem;
4389
+ color: var(--muted);
4390
+ }
4391
+ .support-actions {
4392
+ display: flex;
4393
+ align-items: center;
4394
+ gap: 10px;
4395
+ flex-shrink: 0;
4396
+ }
4397
+ .btn-sponsor {
4398
+ display: inline-flex;
4399
+ align-items: center;
4400
+ gap: 8px;
4401
+ padding: 10px 22px;
4402
+ border: 1px solid var(--accent);
4403
+ border-radius: 999px;
4404
+ background: var(--accent-soft);
4405
+ color: var(--accent-deep);
4406
+ font-size: 0.875rem;
4407
+ text-decoration: none;
4408
+ transition:
4409
+ background 0.2s ease,
4410
+ color 0.2s ease;
4411
+ }
4412
+ .btn-sponsor:hover {
4413
+ background: var(--accent);
4414
+ color: var(--surface);
4415
+ }
4416
+ .btn-sponsor svg {
4417
+ width: 15px;
4418
+ height: 15px;
4419
+ }
4420
+ @media (max-width: 640px) {
4421
+ .support-card {
4422
+ flex-direction: column;
4423
+ align-items: stretch;
4424
+ text-align: center;
4425
+ }
4426
+ .support-actions {
4427
+ justify-content: center;
4428
+ }
4429
+ }
4430
+ .btn-poster {
4431
+ display: inline-flex;
4432
+ align-items: center;
4433
+ gap: 8px;
4434
+ padding: 10px 22px;
4435
+ border: 1px solid var(--border);
4436
+ border-radius: 999px;
4437
+ background: transparent;
4438
+ color: var(--muted);
4439
+ font-size: 0.875rem;
4440
+ cursor: pointer;
4441
+ transition:
4442
+ color 0.2s ease,
4443
+ border-color 0.2s ease;
4444
+ }
4445
+ .btn-poster:hover {
4446
+ color: var(--accent);
4447
+ border-color: var(--accent);
4448
+ }
4449
+ .btn-poster svg {
4450
+ width: 15px;
4451
+ height: 15px;
4452
+ }
4453
+
4454
+ /* 弹窗(z-index 高于 lightbox 320);海报 PNG 固定白底,卡片头部/底部跟随主题 */
4455
+ .poster-modal {
4456
+ position: fixed;
4457
+ inset: 0;
4458
+ z-index: 330;
4459
+ display: flex;
4460
+ align-items: center;
4461
+ justify-content: center;
4462
+ padding: 20px;
4463
+ background: rgba(0, 0, 0, 0.5);
4464
+ backdrop-filter: blur(4px);
4465
+ animation: poster-fade 0.2s ease;
4466
+ }
4467
+ @keyframes poster-fade {
4468
+ from {
4469
+ opacity: 0;
4470
+ }
4471
+ }
4472
+ .poster-card {
4473
+ display: flex;
4474
+ flex-direction: column;
4475
+ width: min(480px, 92vw);
4476
+ max-height: 88vh;
4477
+ background: var(--surface);
4478
+ border: 1px solid var(--border);
4479
+ border-radius: 14px;
4480
+ box-shadow: var(--shadow-md);
4481
+ overflow: hidden;
4482
+ animation: poster-pop 0.25s ease;
4483
+ }
4484
+ @keyframes poster-pop {
4485
+ from {
4486
+ opacity: 0;
4487
+ transform: translateY(12px) scale(0.98);
4488
+ }
4489
+ }
4490
+ .poster-head {
4491
+ display: flex;
4492
+ align-items: center;
4493
+ justify-content: space-between;
4494
+ padding: 12px 16px;
4495
+ border-bottom: 1px solid var(--border);
4496
+ }
4497
+ .poster-head strong {
4498
+ font-size: 0.95rem;
4499
+ color: var(--ink);
4500
+ }
4501
+ .poster-close {
4502
+ display: inline-flex;
4503
+ align-items: center;
4504
+ justify-content: center;
4505
+ width: 30px;
4506
+ height: 30px;
4507
+ border: none;
4508
+ border-radius: var(--radius-sm);
4509
+ background: transparent;
4510
+ color: var(--muted);
4511
+ cursor: pointer;
4512
+ transition:
4513
+ background 0.2s ease,
4514
+ color 0.2s ease;
4515
+ }
4516
+ .poster-close:hover {
4517
+ background: var(--bg-soft);
4518
+ color: var(--ink);
4519
+ }
4520
+ .poster-stage {
4521
+ flex: 1;
4522
+ overflow: auto;
4523
+ padding: 16px;
4524
+ }
4525
+ .poster-img {
4526
+ display: block;
4527
+ width: 100%;
4528
+ height: auto;
4529
+ border-radius: var(--radius-sm);
4530
+ }
4531
+ .poster-loading {
4532
+ display: flex;
4533
+ align-items: center;
4534
+ justify-content: center;
4535
+ gap: 10px;
4536
+ min-height: 160px;
4537
+ color: var(--muted);
4538
+ font-size: 0.875rem;
4539
+ }
4540
+ .poster-spinner {
4541
+ width: 18px;
4542
+ height: 18px;
4543
+ border-radius: 50%;
4544
+ border: 2px solid var(--border);
4545
+ border-top-color: var(--accent);
4546
+ animation: poster-spin 0.8s linear infinite;
4547
+ }
4548
+ @keyframes poster-spin {
4549
+ to {
4550
+ transform: rotate(360deg);
4551
+ }
4552
+ }
4553
+ .poster-foot {
4554
+ display: flex;
4555
+ gap: 10px;
4556
+ padding: 12px 16px;
4557
+ border-top: 1px solid var(--border);
4558
+ }
4559
+ .poster-btn {
4560
+ flex: 1;
4561
+ padding: 9px 0;
4562
+ border: 1px solid var(--border);
4563
+ border-radius: 9px;
4564
+ background: transparent;
4565
+ color: var(--muted);
4566
+ font-size: 0.875rem;
4567
+ cursor: pointer;
4568
+ transition:
4569
+ color 0.2s ease,
4570
+ border-color 0.2s ease;
4571
+ }
4572
+ .poster-btn:hover:not(:disabled) {
4573
+ color: var(--accent);
4574
+ border-color: var(--accent);
4575
+ }
4576
+ .poster-btn:disabled {
4577
+ opacity: 0.5;
4578
+ cursor: not-allowed;
4579
+ }
4580
+ @media (prefers-reduced-motion: reduce) {
4581
+ .poster-modal,
4582
+ .poster-card {
4583
+ animation: none;
4584
+ }
4585
+ .poster-spinner {
4586
+ animation-duration: 2s;
4587
+ }
4588
+ }
4589
+
4590
+ /* ------------------------------------------- image-grid([grid] 图片网格) */
4591
+ .image-grid {
4592
+ display: grid;
4593
+ grid-template-columns: 1fr;
4594
+ align-items: stretch;
4595
+ gap: 1rem;
4596
+ margin: 1.5rem 0;
4597
+ }
4598
+ @media (min-width: 768px) {
4599
+ .image-grid[data-cols="2"] {
4600
+ grid-template-columns: repeat(2, 1fr);
4601
+ }
4602
+ .image-grid[data-cols="3"] {
4603
+ grid-template-columns: repeat(3, 1fr);
4604
+ }
4605
+ .image-grid[data-cols="4"] {
4606
+ grid-template-columns: repeat(4, 1fr);
4607
+ }
4608
+ }
4609
+ .image-grid img {
4610
+ width: 100%;
4611
+ height: 100%;
4612
+ object-fit: cover;
4613
+ border-radius: var(--radius-sm);
4614
+ }
4615
+ /* 覆盖 .prose figure 的边框/背景(网格内图片铺满格子) */
4616
+ .image-grid figure {
4617
+ display: flex;
4618
+ flex-direction: column;
4619
+ height: 100%;
4620
+ width: 100%;
4621
+ margin: 0;
4622
+ padding: 0;
4623
+ border: none;
4624
+ overflow: hidden;
4625
+ border-radius: var(--radius-sm);
4626
+ }
4627
+ .image-grid figure img {
4628
+ flex-grow: 1;
4629
+ min-height: 0;
4630
+ }
4631
+ .image-grid figcaption {
4632
+ margin-top: 0.5rem;
4633
+ margin-bottom: 0;
4634
+ padding: 0 2px;
4635
+ background: transparent;
4636
+ color: var(--ink-2);
4637
+ }
4638
+
4639
+ /* --------------------------------------- card-github(GitHub 仓库卡片) */
4640
+ /* 注意:卡片是 .prose 内的 a 元素,必须覆盖 .prose a 的 border-bottom accent */
4641
+ .prose a.card-github {
4642
+ display: block;
4643
+ position: relative;
4644
+ margin: 1.25rem 0;
4645
+ padding: 1.1rem 1.5rem;
4646
+ color: var(--ink);
4647
+ background: var(--bg-soft);
4648
+ border: 1px solid var(--border);
4649
+ border-radius: var(--radius);
4650
+ text-decoration: none;
4651
+ }
4652
+ .prose a.card-github:hover {
4653
+ background: var(--accent-soft);
4654
+ color: var(--accent-ink);
4655
+ }
4656
+ .prose a.card-github:hover .gc-titlebar {
4657
+ color: var(--accent-ink);
4658
+ }
4659
+ .prose a.card-github:hover .gc-stars,
4660
+ .prose a.card-github:hover .gc-forks,
4661
+ .prose a.card-github:hover .gc-license,
4662
+ .prose a.card-github:hover .gc-description {
4663
+ color: var(--ink);
4664
+ }
4665
+ .prose a.card-github:hover .gc-stars::before,
4666
+ .prose a.card-github:hover .gc-forks::before,
4667
+ .prose a.card-github:hover .gc-license::before {
4668
+ background-color: var(--ink);
4669
+ }
4670
+ .prose a.card-github:active {
4671
+ scale: 0.98;
4672
+ }
4673
+ .prose a.card-github .gc-titlebar {
4674
+ display: flex;
4675
+ align-items: center;
4676
+ justify-content: space-between;
4677
+ margin-bottom: 0.5rem;
4678
+ color: var(--ink);
4679
+ font-size: 1.25rem;
4680
+ font-weight: 500;
4681
+ }
4682
+ .prose a.card-github .gc-titlebar-left {
4683
+ display: flex;
4684
+ flex-flow: row nowrap;
4685
+ gap: 0.5rem;
4686
+ }
4687
+ .prose a.card-github .gc-repo {
4688
+ font-weight: bold;
4689
+ }
4690
+ .prose a.card-github .gc-owner {
4691
+ position: relative;
4692
+ display: flex;
4693
+ flex-flow: row nowrap;
4694
+ align-items: center;
4695
+ gap: 0.5rem;
4696
+ font-weight: 300;
4697
+ }
4698
+ .prose a.card-github .gc-avatar {
4699
+ display: block;
4700
+ overflow: hidden;
4701
+ width: 1.5rem;
4702
+ height: 1.5rem;
4703
+ margin-top: -0.1rem;
4704
+ background-color: var(--accent);
4705
+ background-size: cover;
4706
+ border-radius: 50%;
4707
+ }
4708
+ .prose a.card-github .gc-description {
4709
+ margin-bottom: 0.7rem;
4710
+ font-size: 1rem;
4711
+ font-weight: 300;
4712
+ line-height: 1.5rem;
4713
+ color: var(--ink-2);
4714
+ }
4715
+ .prose a.card-github .gc-infobar {
4716
+ display: flex;
4717
+ flex-flow: row nowrap;
4718
+ gap: 1.5rem;
4719
+ width: fit-content;
4720
+ color: var(--ink-2);
4721
+ }
4722
+ .prose a.card-github .gc-language {
4723
+ display: none;
4724
+ }
4725
+ .prose a.card-github .gc-stars,
4726
+ .prose a.card-github .gc-forks,
4727
+ .prose a.card-github .gc-license,
4728
+ .prose a.card-github .github-logo {
4729
+ font-weight: 500;
4730
+ font-size: 0.875rem;
4731
+ opacity: 0.9;
4732
+ }
4733
+ .prose a.card-github .gc-stars::before,
4734
+ .prose a.card-github .gc-forks::before,
4735
+ .prose a.card-github .gc-license::before,
4736
+ .prose a.card-github .github-logo::before {
4737
+ content: " ";
4738
+ display: inline-block;
4739
+ height: 1.3em;
4740
+ width: 1.3em;
4741
+ margin-right: 0.4rem;
4742
+ vertical-align: -0.24em;
4743
+ font-size: inherit;
4744
+ background-color: var(--ink-2);
4745
+ overflow: visible;
4746
+ -webkit-mask-size: contain;
4747
+ mask-size: contain;
4748
+ -webkit-mask-position: center;
4749
+ mask-position: center;
4750
+ -webkit-mask-repeat: no-repeat;
4751
+ mask-repeat: no-repeat;
4752
+ transition-property: background-color, background;
4753
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
4754
+ transition-duration: 0.15s;
4755
+ }
4756
+ .prose a.card-github .gc-stars::before {
4757
+ -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");
4758
+ 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");
4759
+ }
4760
+ .prose a.card-github .gc-license::before {
4761
+ margin-right: 0.5rem;
4762
+ -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");
4763
+ 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");
4764
+ }
4765
+ .prose a.card-github .gc-forks::before {
4766
+ -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");
4767
+ 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");
4768
+ }
4769
+ .prose a.card-github .github-logo {
4770
+ font-size: 1.25rem;
4771
+ }
4772
+ .prose a.card-github .github-logo::before {
4773
+ margin-right: 0;
4774
+ background-color: var(--ink);
4775
+ -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");
4776
+ 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");
4777
+ }
4778
+ .prose a.card-github.fetch-waiting {
4779
+ pointer-events: none;
4780
+ opacity: 0.7;
4781
+ transition: opacity 0.15s ease-in-out;
4782
+ }
4783
+ .prose a.card-github.fetch-waiting .gc-description,
4784
+ .prose a.card-github.fetch-waiting .gc-infobar,
4785
+ .prose a.card-github.fetch-waiting .gc-avatar {
4786
+ background-color: var(--ink-2);
4787
+ color: transparent;
4788
+ opacity: 0.5;
4789
+ animation: card-pulsate 2s infinite linear;
4790
+ user-select: none;
4791
+ }
4792
+ .prose a.card-github.fetch-waiting .gc-description::before,
4793
+ .prose a.card-github.fetch-waiting .gc-infobar::before,
4794
+ .prose a.card-github.fetch-waiting .gc-avatar::before {
4795
+ background-color: transparent;
4796
+ }
4797
+ .prose a.card-github.fetch-waiting .gc-repo {
4798
+ margin-left: -0.1rem;
4799
+ }
4800
+ .prose a.card-github.fetch-waiting .gc-description,
4801
+ .prose a.card-github.fetch-waiting .gc-infobar {
4802
+ border-radius: 0.5rem;
4803
+ }
4804
+ .prose a.card-github.fetch-error {
4805
+ pointer-events: all;
4806
+ opacity: 1;
4807
+ }
4808
+ @keyframes card-pulsate {
4809
+ 0% {
4810
+ opacity: 0.15;
4811
+ }
4812
+ 50% {
4813
+ opacity: 0.25;
4814
+ }
4815
+ 100% {
4816
+ opacity: 0.15;
4817
+ }
4818
+ }
4819
+ .prose a.card-github,
4820
+ .prose a.card-github .gc-description,
4821
+ .prose a.card-github .gc-titlebar,
4822
+ .prose a.card-github .gc-stars,
4823
+ .prose a.card-github .gc-forks,
4824
+ .prose a.card-github .gc-license,
4825
+ .prose a.card-github .gc-avatar,
4826
+ .prose a.card-github .github-logo {
4827
+ transition-property: all;
4828
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
4829
+ transition-duration: 0.15s;
4830
+ }