hexo-theme-stellar 1.42.0 → 1.43.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 (122) hide show
  1. package/.claude/skills/stellar-theme-dev/SKILL.md +2 -0
  2. package/CHANGELOG.md +42 -0
  3. package/THIRD-PARTY-NOTICES.md +28 -0
  4. package/_config.yml +20 -10
  5. package/_data/icons.yml +10 -9
  6. package/languages/en.yml +11 -0
  7. package/languages/zh-CN.yml +11 -0
  8. package/languages/zh-TW.yml +11 -0
  9. package/layout/_partial/comments/artalk/layout.ejs +1 -1
  10. package/layout/_partial/comments/beaudar/layout.ejs +1 -1
  11. package/layout/_partial/comments/giscus/layout.ejs +1 -1
  12. package/layout/_partial/comments/twikoo/layout.ejs +1 -1
  13. package/layout/_partial/comments/utterances/layout.ejs +1 -1
  14. package/layout/_partial/comments/waline/layout.ejs +1 -1
  15. package/layout/_partial/components/collection-item.ejs +44 -0
  16. package/layout/_partial/components/collection.ejs +26 -0
  17. package/layout/_partial/components/widget-frame.ejs +35 -0
  18. package/layout/_partial/cover/wiki_cover.ejs +82 -26
  19. package/layout/_partial/dropdown.ejs +62 -0
  20. package/layout/_partial/head.ejs +9 -0
  21. package/layout/_partial/main/navbar/breadcrumb/blog.ejs +1 -1
  22. package/layout/_partial/main/post_list/archive_item.ejs +12 -0
  23. package/layout/_partial/main/post_list/topic_card.ejs +21 -9
  24. package/layout/_partial/main/post_list/wiki_card.ejs +49 -10
  25. package/layout/_partial/scripts/bootstrap.ejs +3 -1
  26. package/layout/_partial/scripts/defines.ejs +2 -8
  27. package/layout/_partial/scripts/lazyload.ejs +0 -3
  28. package/layout/_partial/scripts.ejs +1 -0
  29. package/layout/_partial/sidebar/index_leftbar.ejs +12 -2
  30. package/layout/_partial/sidebar/logo.ejs +1 -1
  31. package/layout/_partial/sidebar/menu.ejs +21 -23
  32. package/layout/_partial/widgets/components/linklist.ejs +23 -21
  33. package/layout/_partial/widgets/linklist.ejs +7 -12
  34. package/layout/_partial/widgets/recent.ejs +52 -41
  35. package/layout/_partial/widgets/related.ejs +47 -36
  36. package/layout/_partial/widgets/tagtree.ejs +70 -54
  37. package/layout/_partial/widgets/toc.ejs +37 -62
  38. package/layout/_partial/widgets/tree.ejs +38 -51
  39. package/layout/_plugins/index.ejs +25 -0
  40. package/layout/_plugins/mermaid.ejs +3 -4
  41. package/layout/archive.ejs +11 -20
  42. package/layout/collection-preview.ejs +60 -0
  43. package/layout/index_topic.ejs +12 -6
  44. package/layout/index_wiki.ejs +49 -3
  45. package/layout/layout.ejs +4 -3
  46. package/package.json +1 -1
  47. package/scripts/events/index.js +0 -2
  48. package/scripts/filters/lib/img_lazyload.js +184 -40
  49. package/scripts/generators/stellar-icons.js +1 -1
  50. package/scripts/lib/subtitle.js +5 -1
  51. package/scripts/tags/index.js +1 -0
  52. package/scripts/tags/lib/about.js +1 -1
  53. package/scripts/tags/lib/albums.js +1 -1
  54. package/scripts/tags/lib/banner.js +1 -1
  55. package/scripts/tags/lib/dropdown.js +64 -0
  56. package/scripts/tags/lib/friends.js +1 -1
  57. package/scripts/tags/lib/gallery.js +3 -3
  58. package/scripts/tags/lib/image.js +1 -1
  59. package/scripts/tags/lib/posters.js +1 -1
  60. package/scripts/tags/lib/sites.js +8 -4
  61. package/source/css/_common/base.styl +4 -4
  62. package/source/css/_common/blockquote.styl +2 -2
  63. package/source/css/_common/dropdown.styl +132 -0
  64. package/source/css/_common/html.styl +1 -1
  65. package/source/css/_common/loading.styl +5 -2
  66. package/source/css/_common/title.styl +8 -8
  67. package/source/css/_components/collection.styl +188 -0
  68. package/source/css/_components/layout.styl +1 -1
  69. package/source/css/_components/list.styl +44 -46
  70. package/source/css/_components/md.styl +3 -3
  71. package/source/css/_components/page-transition.styl +22 -0
  72. package/source/css/_components/pages/archives.styl +19 -18
  73. package/source/css/_components/pages/article-indent.styl +2 -2
  74. package/source/css/_components/pages/article-story.styl +9 -5
  75. package/source/css/_components/pages/collection-preview.styl +68 -0
  76. package/source/css/_components/pages/notebook.styl +11 -9
  77. package/source/css/_components/partial/article-footer.styl +7 -4
  78. package/source/css/_components/partial/cover.styl +280 -1
  79. package/source/css/_components/partial/related.styl +10 -6
  80. package/source/css/_components/sidebar/footer.styl +65 -12
  81. package/source/css/_components/sidebar/nav-area.styl +6 -1
  82. package/source/css/_components/sidebar/search.styl +6 -2
  83. package/source/css/_components/tag-plugins/chat.styl +1 -1
  84. package/source/css/_components/tag-plugins/folders.styl +4 -4
  85. package/source/css/_components/tag-plugins/folding.styl +3 -3
  86. package/source/css/_components/tag-plugins/hashtag.styl +2 -3
  87. package/source/css/_components/tag-plugins/mdrender.styl +1 -1
  88. package/source/css/_components/tag-plugins/note.styl +4 -4
  89. package/source/css/_components/tag-plugins/poetry.styl +5 -5
  90. package/source/css/_components/tag-plugins/quot.styl +1 -2
  91. package/source/css/_components/tag-plugins/quote.styl +1 -1
  92. package/source/css/_components/tag-plugins/tabs.styl +2 -2
  93. package/source/css/_components/tag-plugins/timeline.styl +4 -4
  94. package/source/css/_components/widgets/ghrepo.styl +4 -0
  95. package/source/css/_components/widgets/markdown.styl +1 -14
  96. package/source/css/_components/widgets/timeline.styl +2 -2
  97. package/source/css/_components/widgets/toc.styl +22 -20
  98. package/source/css/_components/widgets/widgets.styl +13 -1
  99. package/source/css/_components/wiki-card.styl +209 -0
  100. package/source/css/_custom.styl +22 -20
  101. package/source/css/_plugins/lazyload.styl +8 -5
  102. package/source/css/comments/utterances.styl +2 -2
  103. package/source/css/comments/waline.styl +24 -0
  104. package/source/css/plugins/mermaid.styl +31 -12
  105. package/source/js/icons.js +1 -1
  106. package/source/js/main.js +62 -6
  107. package/source/js/plugins/adaptive-text.js +46 -2
  108. package/source/js/plugins/dropdown.js +435 -0
  109. package/source/js/plugins/galaxy.js +423 -0
  110. package/source/js/search/algolia-search.js +1 -1
  111. package/source/js/search/local-search.js +1 -1
  112. package/source/js/services/ghinfo.js +31 -3
  113. package/source/js/services/siteinfo.js +26 -0
  114. package/source/js/services/sites.js +6 -2
  115. package/source/js/services.js +5 -2
  116. package/source/js/tagtree.js +7 -7
  117. package/source/js/utils.js +1 -1
  118. package/layout/_partial/widgets/components/link.ejs +0 -21
  119. package/source/css/_components/sidebar/menu.styl +0 -77
  120. package/source/css/_components/widgets/components.styl +0 -68
  121. package/source/css/_components/widgets/list.styl +0 -46
  122. package/source/css/_components/widgets/related.styl +0 -40
@@ -17,14 +17,14 @@
17
17
 
18
18
  var index = 0
19
19
 
20
- function img(src, alt, loading) {
20
+ function img(src, alt) {
21
21
  let img = ''
22
22
  img += `<img class="lazy" data-fancybox="gallery-${index}" data-src="${src}"`
23
23
  if (alt?.length > 0) {
24
24
  img += ` alt="${alt}"`
25
25
  }
26
26
  img += `/>`
27
- img += `<div class="lazy-icon" style="background-image:url(${loading});"></div>`
27
+ img += `<div class="lazy-icon"></div>`
28
28
  // cap
29
29
  img += `<div class="image-meta">`
30
30
  if (alt?.length > 0) {
@@ -55,7 +55,7 @@ module.exports = ctx => function(args, content) {
55
55
  if (matches?.length > 2) {
56
56
  let alt = matches[1]
57
57
  let src = matches[2]
58
- el += `<div class="${layoutType}-cell lazy-box">${img(src, alt, ctx.theme.config.default.loading || ctx.utils.iconData('default:loading-placeholder'))}</div>`
58
+ el += `<div class="${layoutType}-cell lazy-box">${img(src, alt)}</div>`
59
59
  }
60
60
  }
61
61
  el += `</div>`
@@ -50,7 +50,7 @@ module.exports = ctx => function(args) {
50
50
  img += `onerror="this.src=&quot;${ctx.theme.config.default.image_onerror || ctx.utils.iconData('image:onerror')}&quot;"`
51
51
  img += '/>'
52
52
  // loading
53
- img += `<div class="lazy-icon" style="background-image:url(${ctx.theme.config.default.loading || ctx.utils.iconData('default:loading-placeholder')});"></div>`
53
+ img += `<div class="lazy-icon"></div>`
54
54
  if (fancyboxHref) {
55
55
  a += ` href="${fancyboxHref}">${img}</a>`
56
56
  return a
@@ -32,7 +32,7 @@ module.exports = ctx => function(args) {
32
32
  el += `<div class="grid-cell poster-card">`
33
33
  el += `<a class="card-link lazy-box" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
34
34
  el += `<img class="lazy" data-src="${item.cover || item.icon || item.avatar || ctx.theme.config.default.cover}" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;${ctx.theme.config.default.cover}&quot;;"/>`
35
- el += `<div class="lazy-icon" style="background-image:url(${ctx.theme.config.default.loading || ctx.utils.iconData('default:loading-placeholder')});"></div>`
35
+ el += `<div class="lazy-icon"></div>`
36
36
  el += `<div class="image-meta">`
37
37
  if (item.title) {
38
38
  el += `<span class="image-caption">${item.title}</span>`
@@ -10,6 +10,7 @@
10
10
  module.exports = ctx => function(args) {
11
11
  args = ctx.args.map(args, ['repo', 'api'], ['group'])
12
12
  const host = ctx.theme.config.api_host.ghraw
13
+ const siteinfoApi = ctx.theme.config.data_services.siteinfo?.api
13
14
  var api
14
15
  if (args.api) {
15
16
  api = args.api
@@ -29,16 +30,19 @@ module.exports = ctx => function(args) {
29
30
  el += '<div class="grid-box">'
30
31
  for (let item of (links[args.group] || [])) {
31
32
  if (item?.url && item?.title) {
33
+ const itemSiteinfoApi = !item.icon && !item.avatar && siteinfoApi
34
+ ? siteinfoApi.replace('{href}', item.url)
35
+ : ''
32
36
  el += `<div class="grid-cell site-card">`
33
- el += `<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
37
+ el += `<a class="card-link"${itemSiteinfoApi ? ` data-siteinfo-api="${itemSiteinfoApi}"` : ''} target="_blank" rel="external nofollow noopener noreferrer" href="${item.url}">`
34
38
  el += `<div class="lazy-box snapshot">`
35
39
  el += `<img class="lazy" data-src="${item.cover || item.snapshot || item.screenshot || ('https://image.thum.io/get/width/1280/crop/720/' + item.url)}" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;${ctx.theme.config.default.cover}&quot;;"/>`
36
- el += `<div class="lazy-icon" style="background-image:url(&quot;${ctx.theme.config.default.loading || ctx.utils.iconData('default:loading-placeholder')}&quot;);"></div>`
40
+ el += `<div class="lazy-icon"></div>`
37
41
  el += `</div>`
38
42
  el += `<div class="info">`
39
43
  el += `<div class="lazy-box icon">`
40
- el += `<img class="lazy" data-src="${item.icon || item.avatar || ctx.theme.config.default.link}" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;${item.icon || item.avatar || ctx.theme.config.default.link}&quot;;"/>`
41
- el += `<div class="lazy-icon" style="background-image:url(&quot;${ctx.theme.config.default.loading || ctx.utils.iconData('default:loading-placeholder')}&quot;);"></div>`
44
+ el += `<img class="lazy siteinfo-icon" data-src="${item.icon || item.avatar || ctx.theme.config.default.link}" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;${item.icon || item.avatar || ctx.theme.config.default.link}&quot;;"/>`
45
+ el += `<div class="lazy-icon"></div>`
42
46
  el += `</div>`
43
47
  el += `<span class="title">${item.title}</span>`
44
48
  el += `<span class="desc">${item.description || item.url}</span>`
@@ -24,11 +24,11 @@ img
24
24
  max-width: 100%
25
25
 
26
26
  li
27
- font-size: 'calc(%s - 1px)' % var(--fsp)
27
+ font-size: 'calc(%s - 1px)' % var(--fs-content)
28
28
 
29
29
 
30
30
  ul,ol
31
- padding-left: var(--fsp)
31
+ padding-left: var(--fs-content)
32
32
 
33
33
 
34
34
  // table
@@ -40,8 +40,8 @@ table:not([class])
40
40
  margin: 1rem 0
41
41
  max-width: 100%
42
42
  vertical-align: text-top
43
- --fsp: $fsp2
44
- font-size: var(--fsp)
43
+ --fs-content: $fs-content-2
44
+ font-size: var(--fs-content)
45
45
  scrollbar(0,0)
46
46
  th
47
47
  background: var(--block)
@@ -2,7 +2,7 @@ blockquote
2
2
  display: block
3
3
  margin-left: 0
4
4
  margin-right: 0
5
- padding: 0 var(--fsp)
5
+ padding: 0 var(--fs-content)
6
6
  $bd-left = 4px
7
7
  color: var(--text-p3)
8
8
  position: relative
@@ -18,4 +18,4 @@ blockquote
18
18
  opacity: 0.5
19
19
  background: var(--text-meta)
20
20
  &:hover:before
21
- background: var(--theme)
21
+ background: var(--theme)
@@ -0,0 +1,132 @@
1
+ .dropdown
2
+ position: relative
3
+ display: inline-block
4
+ z-index: 0
5
+ overflow: visible
6
+ line-height: 1
7
+ font-size: $fs-14
8
+ >.dropdown-trigger
9
+ display: inline-flex
10
+ align-items: center
11
+ gap: 0.5rem
12
+ box-sizing: border-box
13
+ min-height: 2rem
14
+ padding: 0.5rem 0.75rem
15
+ cursor: pointer
16
+ list-style: none
17
+ outline: none
18
+ border-radius: $border-bar
19
+ color: var(--text-p2)
20
+ background: var(--block)
21
+ text-decoration: none
22
+ white-space: nowrap
23
+ &::-webkit-details-marker
24
+ display: none
25
+ &::marker
26
+ display: none
27
+ &:hover, &:focus-visible
28
+ color: var(--text-p1)
29
+ background: var(--block-border)
30
+ >svg, >img, >.icon
31
+ flex: 0 0 1.25rem
32
+ width: 1.25rem
33
+ height: 1.25rem
34
+ >.dropdown-arrow
35
+ transition: transform 0.2s ease
36
+ >span
37
+ overflow: hidden
38
+ text-overflow: ellipsis
39
+ &[open]
40
+ z-index: 10
41
+ >.dropdown-trigger
42
+ color: var(--text-p1)
43
+ background: var(--block-border)
44
+ >.dropdown-arrow
45
+ transform: rotate(180deg)
46
+ .dropdown-menu
47
+ display: flex
48
+ flex-direction: column
49
+ gap: 0.125rem
50
+ box-sizing: border-box
51
+ max-width: calc(100vw - 2rem)
52
+ max-height: calc(100vh - 2rem)
53
+ padding: 0.25rem
54
+ overflow-x: hidden
55
+ overflow-y: auto
56
+ font-size: $fs-14
57
+ border: 1px solid var(--block-border)
58
+ border-radius: $border-card
59
+ corner-shape: $corner-shape
60
+ background: rgba(white, 0.3)
61
+ box-shadow: 0 0 2px rgba(black, .04), 0 2px 8px rgba(black, .04), 0 4px 16px rgba(black, .04)
62
+ backdrop-filter: saturate(300%) blur(16px)
63
+ -webkit-backdrop-filter: saturate(300%) blur(16px)
64
+ :root[data-theme="dark"] &
65
+ background: rgba(white, 0.2)
66
+ :root:not([data-theme]) &
67
+ @media (prefers-color-scheme: dark)
68
+ background: rgba(white, 0.2)
69
+ text-align: left
70
+ line-height: 1
71
+
72
+ .dropdown-menu.ui-collection[data-density='compact']
73
+ min-width: 150px
74
+ --ui-item-min-height: calc(1.5rem + 2 * var(--ui-item-padding-y))
75
+
76
+ .dropdown > .dropdown-menu
77
+ position: absolute
78
+ z-index: 10
79
+ top: calc(100% + 0.5rem)
80
+ left: 50%
81
+ transform: translateX(-50%)
82
+ visibility: hidden
83
+
84
+ .dropdown[direction=up] > .dropdown-menu
85
+ top: auto
86
+ bottom: calc(100% + 0.5rem)
87
+
88
+ .dropdown[align=left] > .dropdown-menu
89
+ left: 0
90
+ transform: none
91
+
92
+ .dropdown[align=right] > .dropdown-menu
93
+ right: 0
94
+ left: auto
95
+ transform: none
96
+
97
+ .dropdown-layer
98
+ position: fixed
99
+ z-index: 1000
100
+ top: 0
101
+ right: 0
102
+ bottom: 0
103
+ left: 0
104
+ pointer-events: none
105
+ > .dropdown-bridge
106
+ position: fixed
107
+ z-index: 0
108
+ top: 0
109
+ right: 0
110
+ bottom: 0
111
+ left: 0
112
+ pointer-events: auto
113
+ background: transparent
114
+ > .dropdown-menu
115
+ position: fixed
116
+ z-index: 1000
117
+ top: 0
118
+ left: 0
119
+ transform: none
120
+ pointer-events: auto
121
+ visibility: hidden
122
+ opacity: 0
123
+ contain: paint
124
+ will-change: opacity
125
+ transition: opacity 0.16s ease-out
126
+ &.dropdown-menu-visible
127
+ visibility: visible
128
+ opacity: 1
129
+
130
+ @media (prefers-reduced-motion: reduce)
131
+ .dropdown-layer > .dropdown-menu, .dropdown > .dropdown-trigger > .dropdown-arrow
132
+ transition: none
@@ -7,7 +7,7 @@ html
7
7
  scrollbar(8px,8px)
8
8
  overflow-y: scroll
9
9
  font-family: $ff-body
10
- font-size: $fs-root
10
+ font-size: var(--fs-root)
11
11
  -webkit-text-size-adjust: 100%
12
12
  -ms-text-size-adjust: 100%
13
13
  scroll-padding-top: 0
@@ -22,8 +22,11 @@ svg.loading
22
22
  border-radius: $border-card
23
23
  position relative
24
24
  padding: 2rem
25
- svg
25
+ svg,
26
+ .lazy-icon
26
27
  margin: 4px
28
+ .lazy-icon
29
+ display: inline-block
27
30
  &:after
28
31
  content: hexo-config('style.loading.loading')
29
32
  color: var(--text-p1)
@@ -35,4 +38,4 @@ svg.loading
35
38
 
36
39
  .article-footer
37
40
  .loading-wrap
38
- background: none
41
+ background: none
@@ -11,9 +11,9 @@ h3,.h3
11
11
  h4,.h4
12
12
  font-size: var(--fsh4)
13
13
  h5
14
- font-size: 'calc(%s + 1px)' % var(--fsp)
14
+ font-size: 'calc(%s + 1px)' % var(--fs-content)
15
15
  h6
16
- font-size: 'calc(%s + 0px)' % var(--fsp)
16
+ font-size: 'calc(%s + 0px)' % var(--fs-content)
17
17
 
18
18
  // story 文章段落标题(h2):居中 + 两侧 accent 斜杠装饰
19
19
  // 专栏列表页专栏标题(.topic-title)与 story 文章 h2 共用
@@ -34,15 +34,15 @@ story-title()
34
34
 
35
35
  // 次级段落字号
36
36
  .fs15
37
- --fsp: $fs-15
38
- font-size: var(--fsp)
37
+ --fs-content: $fs-15
38
+ font-size: var(--fs-content)
39
39
  .fs14
40
- --fsp: $fs-14
41
- font-size: var(--fsp)
40
+ --fs-content: $fs-14
41
+ font-size: var(--fs-content)
42
42
 
43
43
  .footnote
44
- --fsp: $fs-13
45
- font-size: var(--fsp)
44
+ --fs-content: $fs-13
45
+ font-size: var(--fs-content)
46
46
 
47
47
  .widgets
48
48
  .post-title
@@ -0,0 +1,188 @@
1
+ // 可移植的紧凑列表/网格只读取 surface 语义变量,不感知所在页面区域。
2
+ [data-ui-surface]
3
+ --ui-item-bg: transparent
4
+ --ui-item-bg-hover: var(--block)
5
+ --ui-item-bg-active: var(--block)
6
+ --ui-item-shadow-hover: none
7
+ --ui-item-shadow-active: none
8
+ --ui-item-title: var(--text-p1)
9
+ --ui-item-muted: var(--text-p3)
10
+ --ui-item-padding-x: var(--gap-base)
11
+ --ui-item-padding-y: 8px
12
+ --ui-item-min-height: 32px
13
+ --ui-collection-gap: 4px
14
+
15
+ [data-ui-surface='glass']
16
+ --ui-item-bg-hover: linear-gradient(180deg, rgba(white, .38), rgba(white, 0) 50%), var(--bg-a50)
17
+ --ui-item-bg-active: linear-gradient(180deg, rgba(white, .38), rgba(white, 0) 50%), var(--bg-a50)
18
+ --ui-item-shadow-hover: inset 0 1px 0 rgba(white, .45)
19
+ --ui-item-shadow-active: inset 0 1px 0 rgba(white, .45)
20
+ :root[data-theme='dark'] &
21
+ --ui-item-bg-hover: linear-gradient(180deg, rgba(white, .08), rgba(white, 0) 50%), var(--bg-a20)
22
+ --ui-item-bg-active: linear-gradient(180deg, rgba(white, .08), rgba(white, 0) 50%), var(--bg-a20)
23
+ --ui-item-shadow-hover: inset 0 1px 0 rgba(white, .08)
24
+ --ui-item-shadow-active: inset 0 1px 0 rgba(white, .08)
25
+ :root:not([data-theme]) &
26
+ @media screen and (prefers-color-scheme: dark)
27
+ --ui-item-bg-hover: linear-gradient(180deg, rgba(white, .08), rgba(white, 0) 50%), var(--bg-a20)
28
+ --ui-item-bg-active: linear-gradient(180deg, rgba(white, .08), rgba(white, 0) 50%), var(--bg-a20)
29
+ --ui-item-shadow-hover: inset 0 1px 0 rgba(white, .08)
30
+ --ui-item-shadow-active: inset 0 1px 0 rgba(white, .08)
31
+
32
+ .ui-collection
33
+ --ui-columns: 1
34
+ --ui-grid-min: 7rem
35
+ --ui-item-depth: 0
36
+ display: grid
37
+ gap: var(--ui-collection-gap)
38
+ min-width: 0
39
+
40
+ .ui-collection[data-layout='list']
41
+ grid-template-columns: minmax(0, 1fr)
42
+
43
+ .ui-collection[data-layout='grid']
44
+ grid-template-columns: unquote('repeat(auto-fit, minmax(min(100%, max(var(--ui-grid-min), calc((100% - (var(--ui-columns) - 1) * var(--ui-collection-gap)) / var(--ui-columns)))), 1fr))')
45
+
46
+ .ui-collection[data-density='compact']
47
+ --ui-item-padding-y: 4px
48
+ --ui-item-min-height: 30px
49
+ --ui-collection-gap: 2px
50
+
51
+ .ui-collection__item
52
+ --item-theme-light: x-theme-light()
53
+ box-sizing: border-box
54
+ min-width: 0
55
+ min-height: var(--ui-item-min-height)
56
+ padding: var(--ui-item-padding-y) var(--ui-item-padding-x)
57
+ padding-left: calc(var(--ui-item-padding-x) + var(--ui-item-depth) * var(--gap-base))
58
+ border-radius: $border-bar
59
+ color: var(--text-p2)
60
+ background: var(--ui-item-bg)
61
+ box-shadow: none
62
+ display: flex
63
+ align-items: center
64
+ gap: 12px
65
+ line-height: 1.2
66
+ position: relative
67
+ &:hover
68
+ color: var(--ui-item-title)
69
+ background: var(--ui-item-bg-hover)
70
+ box-shadow: var(--ui-item-shadow-hover)
71
+ &.is-active
72
+ color: var(--ui-item-title)
73
+ background: var(--ui-item-bg-active)
74
+ box-shadow: var(--ui-item-shadow-active)
75
+ &:focus-visible
76
+ outline: 2px solid var(--theme)
77
+ outline-offset: 2px
78
+
79
+ .ui-collection__leading
80
+ width: 1.5rem
81
+ height: 1.5rem
82
+ flex-shrink: 0
83
+ display: flex
84
+ align-items: center
85
+ justify-content: center
86
+ color: var(--text-p2)
87
+ img,svg
88
+ max-width: 100%
89
+ max-height: 100%
90
+ object-fit: contain
91
+ opacity: .5
92
+
93
+ .ui-collection__content
94
+ min-width: 0
95
+ flex: 1
96
+ display: flex
97
+ flex-direction: column
98
+ gap: 4px
99
+
100
+ .ui-collection[data-variant='nav'] .ui-collection__content
101
+ display: block
102
+ txt-ellipsis()
103
+ .ui-collection__prefix,
104
+ .ui-collection__title
105
+ display: inline
106
+
107
+ .ui-collection__prefix
108
+ color: var(--text-p2)
109
+ font-size: $fs-12
110
+ font-weight: 700
111
+ txt-ellipsis()
112
+ &:after
113
+ content: ''
114
+ display: inline-block
115
+ width: 4px
116
+ height: 4px
117
+ margin: 0 4px 2px
118
+ border-radius: 50%
119
+ background: currentColor
120
+ opacity: .35
121
+
122
+ .ui-collection__title
123
+ color: inherit
124
+ font-size: $fs-14
125
+ font-weight: 500
126
+ txt-ellipsis()
127
+
128
+ .ui-collection__description
129
+ color: var(--ui-item-muted)
130
+ font-size: $fs-12
131
+ line-height: 1.4
132
+ display: -webkit-box
133
+ -webkit-box-orient: vertical
134
+ -webkit-line-clamp: 2
135
+ overflow: hidden
136
+
137
+ .ui-collection__meta
138
+ color: var(--ui-item-muted)
139
+ font-size: $fs-12
140
+ txt-ellipsis()
141
+
142
+ .ui-collection__indicator
143
+ flex-shrink: 0
144
+ width: 8px
145
+ height: 8px
146
+ border-radius: 50%
147
+ corner-shape: round
148
+ background: x-theme-gradient()
149
+
150
+ .ui-collection__item:hover,
151
+ .ui-collection__item.is-active
152
+ .ui-collection__leading
153
+ color: var(--item-theme, var(--theme))
154
+ img,svg
155
+ opacity: 1
156
+ svg [fill='currentColor']
157
+ fill: var(--item-grad, currentColor)
158
+ svg [stroke='currentColor']
159
+ stroke: var(--item-grad, currentColor)
160
+
161
+ .ui-collection[data-layout='grid']
162
+ .ui-collection__indicator
163
+ display: none
164
+
165
+ .ui-collection[data-variant='icon']
166
+ --ui-grid-min: 3rem
167
+ .ui-collection__item
168
+ justify-content: center
169
+ text-align: center
170
+ padding-left: var(--ui-item-padding-x)
171
+ .ui-collection__content
172
+ flex: initial
173
+
174
+ .ui-collection[data-variant='summary'] .ui-collection__item
175
+ align-items: flex-start
176
+ border-radius: $border-card-s
177
+ padding-top: 8px
178
+ padding-bottom: 8px
179
+ .ui-collection__title
180
+ font-weight: 700
181
+ .ui-collection__content
182
+ display: flex
183
+
184
+ .ui-collection-adapter
185
+ --ui-adapter-bg-hover: var(--ui-item-bg-hover)
186
+ --ui-adapter-bg-active: var(--ui-item-bg-active)
187
+ --ui-adapter-shadow-hover: var(--ui-item-shadow-hover)
188
+ --ui-adapter-shadow-active: var(--ui-item-shadow-active)
@@ -3,7 +3,7 @@
3
3
  grid-template-columns: 1fr minmax(200px,var(--width-main)) 1fr
4
4
  grid-gap: calc(var(--gap-page) * 1)
5
5
  margin: auto
6
- font-size: var(--fsp)
6
+ font-size: var(--fs-content)
7
7
 
8
8
  .l_body aside
9
9
  z-index: 8
@@ -104,8 +104,8 @@
104
104
  flex-wrap: wrap
105
105
  margin: 0
106
106
  line-height: 2
107
- --fsp: $fsp1
108
- font-size: var(--fsp)
107
+ --fs-content: $fs-content-1
108
+ font-size: var(--fs-content)
109
109
  svg
110
110
  height: 1em
111
111
  width: auto
@@ -217,46 +217,6 @@
217
217
  font-size: $fsh4
218
218
 
219
219
 
220
- // wiki
221
- .post-list .post-card.wiki article
222
- display: flex
223
- flex-wrap: wrap
224
- trans1 box-shadow
225
- justify-content: center
226
- padding: 1rem .5rem
227
-
228
-
229
- .post-list .post-card.wiki article .preview
230
- display: flex
231
- margin: 1rem 3rem
232
- align-items: center
233
- img
234
- width: 96px
235
- max-height: 96px
236
- object-fit: contain
237
- trans1: all 0.75s
238
- .post-list .post-card.wiki article .excerpt
239
- margin: 1rem .5rem
240
- @media screen and (min-width: 950px)
241
- margin-right: 2rem
242
- min-width: 280px
243
- flex: 1
244
- overflow: hidden
245
- word-wrap: break-word
246
- .caps
247
- line-height: 1
248
- margin-bottom: 0.75rem
249
- .cap
250
- --theme-block: var(--block)
251
- background: var(--theme-block)
252
- padding: 2px 4px
253
- border-radius: 4px
254
- p:last-child
255
- margin-bottom: 0
256
- .cap+.cap
257
- margin-left: 4px
258
-
259
-
260
220
  // topic 专栏列表:平铺容器 + 上下布局(h2 专栏标题 → 最新文章卡片 → 文章链接列表)
261
221
  .post-list.topic
262
222
  .post-card-wrap
@@ -287,7 +247,7 @@
287
247
  color: var(--text-p2)
288
248
  font-size: $fs-14
289
249
  line-height: 1.5
290
- // 左右内边距与文章列表(.post-panel padding: 0 1rem)一致
250
+ // 左右内边距与下方归档式文章列表一致
291
251
  padding: 0 1rem
292
252
  margin: 0 0 1rem
293
253
  .cover
@@ -308,13 +268,51 @@
308
268
  img
309
269
  width: 100%
310
270
  height: 100%
311
- .post-panel
271
+ .topic-posts
312
272
  flex: none
313
273
  width: 100%
274
+ margin: 0
314
275
  // 左右内边距与文章封面文字区(.cover-info padding: 1rem)一致
315
276
  padding: 0 1rem
316
- .posts
317
- margin: 0
277
+ .topic-posts-more[open]
278
+ display: flex
279
+ flex-direction: column
280
+ .topic-posts-extra
281
+ order: 1
282
+ .topic-posts-toggle
283
+ order: 2
284
+ .topic-posts-toggle
285
+ display: flex
286
+ align-items: center
287
+ justify-content: center
288
+ gap: .35em
289
+ width: 100%
290
+ margin-top: .5rem
291
+ padding: .75rem 0
292
+ list-style: none
293
+ cursor: pointer
294
+ color: var(--text-p3)
295
+ font-size: $fs-13
296
+ font-weight: 500
297
+ trans1 color
298
+ &::-webkit-details-marker
299
+ display: none
300
+ .when-open
301
+ display: none
302
+ svg
303
+ width: 1em
304
+ height: 1em
305
+ transform: rotate(90deg)
306
+ trans1 transform
307
+ &:hover
308
+ color: var(--accent)
309
+ .topic-posts-more[open] .topic-posts-toggle
310
+ .when-closed
311
+ display: none
312
+ .when-open
313
+ display: inline
314
+ svg
315
+ transform: rotate(-90deg)
318
316
  // hover 放大覆盖(与 photo 卡片一致,见 .post-card.post.photo:hover 注释)
319
317
  .post-card.topic:hover
320
318
  .cover:before
@@ -27,8 +27,8 @@
27
27
  margin: 0 .25rem
28
28
  blockquote,ul,ol
29
29
  p,ul,ol
30
- --fsp: $fsp1
31
- font-size: var(--fsp)
30
+ --fs-content: $fs-content-1
31
+ font-size: var(--fs-content)
32
32
  line-height: 1.5
33
33
  code
34
34
  font-size: inherit
@@ -59,7 +59,7 @@
59
59
  margin-top: 0
60
60
 
61
61
  .md-text p
62
- font-size: var(--fsp)
62
+ font-size: var(--fs-content)
63
63
 
64
64
  .md-text pre
65
65
  -webkit-font-smoothing: auto
@@ -0,0 +1,22 @@
1
+ // 同源整页导航使用浏览器原生 View Transition 平滑衔接。
2
+ // 不支持该能力的浏览器会忽略这些规则,继续使用普通整页导航。
3
+ if hexo-config('style.page_transition.enable')
4
+ @view-transition
5
+ navigation: auto
6
+
7
+ // 左栏独立于根快照过渡,内容未变化时避免随整页一起闪烁。
8
+ .l_left
9
+ view-transition-name: leftbar
10
+
11
+ ::view-transition-group(root),
12
+ ::view-transition-old(root),
13
+ ::view-transition-new(root),
14
+ ::view-transition-group(leftbar),
15
+ ::view-transition-old(leftbar),
16
+ ::view-transition-new(leftbar)
17
+ animation-duration: 0.2s
18
+ animation-timing-function: ease-out
19
+
20
+ @media (prefers-reduced-motion: reduce)
21
+ @view-transition
22
+ navigation: none