hexo-theme-stellar 1.37.0 → 1.38.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 (67) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/_config.yml +13 -8
  3. package/languages/en.yml +37 -0
  4. package/languages/zh-CN.yml +37 -0
  5. package/languages/zh-TW.yml +37 -0
  6. package/layout/_partial/comments/layout.ejs +2 -1
  7. package/layout/_partial/main/navbar/article_banner.ejs +11 -5
  8. package/layout/_partial/main/post_list/post_card.ejs +1 -1
  9. package/layout/_partial/scripts/defines.ejs +2 -1
  10. package/layout/_partial/scripts/utils.ejs +58 -15
  11. package/layout/_partial/sidebar/grad-def.ejs +26 -0
  12. package/layout/_partial/sidebar/index_leftbar.ejs +25 -10
  13. package/layout/_partial/sidebar/logo.ejs +21 -0
  14. package/layout/_partial/sidebar/menu.ejs +11 -5
  15. package/layout/_partial/widgets/toc.ejs +12 -8
  16. package/layout/_plugins/scrollreveal.ejs +17 -2
  17. package/layout/index.ejs +27 -1
  18. package/layout/notebooks.ejs +3 -1
  19. package/layout/notes.ejs +3 -1
  20. package/package.json +1 -1
  21. package/scripts/tags/index.js +1 -0
  22. package/scripts/tags/lib/mbti.js +169 -0
  23. package/source/css/_common/canonical.styl +9 -10
  24. package/source/css/_common/highlight.styl +0 -2
  25. package/source/css/_common/html.styl +2 -1
  26. package/source/css/_common/svg.styl +9 -1
  27. package/source/css/_components/list.styl +36 -16
  28. package/source/css/_components/md.styl +0 -1
  29. package/source/css/_components/pages/article-story.styl +1 -3
  30. package/source/css/_components/partial/article-banner.styl +17 -11
  31. package/source/css/_components/partial/article-footer.styl +0 -1
  32. package/source/css/_components/partial/navbar.styl +3 -3
  33. package/source/css/_components/sidebar/logo.styl +26 -0
  34. package/source/css/_components/sidebar/menu.styl +53 -30
  35. package/source/css/_components/sidebar/nav-area.styl +1 -1
  36. package/source/css/_components/sidebar/search.styl +46 -7
  37. package/source/css/_components/sidebar/sidebar.styl +5 -1
  38. package/source/css/_components/tag-plugins/banner.styl +2 -1
  39. package/source/css/_components/tag-plugins/chat.styl +3 -1
  40. package/source/css/_components/tag-plugins/folding.styl +1 -2
  41. package/source/css/_components/tag-plugins/friends.styl +1 -0
  42. package/source/css/_components/tag-plugins/friends_posts.styl +2 -1
  43. package/source/css/_components/tag-plugins/gallery.styl +1 -2
  44. package/source/css/_components/tag-plugins/grid.styl +1 -2
  45. package/source/css/_components/tag-plugins/image.styl +0 -2
  46. package/source/css/_components/tag-plugins/link.styl +0 -1
  47. package/source/css/_components/tag-plugins/mbti.styl +80 -0
  48. package/source/css/_components/tag-plugins/note.styl +1 -2
  49. package/source/css/_components/tag-plugins/okr.styl +1 -2
  50. package/source/css/_components/tag-plugins/sites.styl +0 -1
  51. package/source/css/_components/tag-plugins/timeline.styl +1 -6
  52. package/source/css/_components/widgets/components.styl +14 -7
  53. package/source/css/_components/widgets/ghuser.styl +2 -1
  54. package/source/css/_components/widgets/list.styl +20 -8
  55. package/source/css/_components/widgets/markdown.styl +4 -1
  56. package/source/css/_components/widgets/related.styl +6 -4
  57. package/source/css/_components/widgets/toc.styl +2 -2
  58. package/source/css/_components/widgets/widgets.styl +6 -9
  59. package/source/css/_custom.styl +2 -1
  60. package/source/css/_defines/const.styl +1 -1
  61. package/source/css/_defines/func.styl +13 -1
  62. package/source/css/_defines/theme_base.styl +22 -1
  63. package/source/css/_plugins/comments/artalk.styl +2 -2
  64. package/source/css/_plugins/comments/twikoo.styl +0 -2
  65. package/source/css/_plugins/tianli_gpt.styl +3 -0
  66. package/source/js/main.js +39 -17
  67. package/source/js/services/memos.js +12 -3
package/layout/index.ejs CHANGED
@@ -5,6 +5,29 @@ if (page.menu_id == undefined) {
5
5
  if (page.title && page.wiki) {
6
6
  page.robots = 'noindex,follow';
7
7
  }
8
+ // 首页评论区:仅首页第一页,默认不显示,可通过 site_tree.home.comments 开启/覆盖
9
+ var homeCmt = theme.site_tree?.home?.comments
10
+ if (homeCmt && homeCmt !== false && is_home_first_page()) {
11
+ page.comments = true;
12
+ if (typeof homeCmt === 'object') {
13
+ if (homeCmt.service) {
14
+ page.comments_service = homeCmt.service;
15
+ }
16
+ if (homeCmt.comment_title != null) {
17
+ page.comment_title = homeCmt.comment_title;
18
+ }
19
+ if (homeCmt.comment_id != null) {
20
+ page.comment_id = homeCmt.comment_id;
21
+ }
22
+ var homeCommentServices = ['beaudar', 'utterances', 'giscus', 'twikoo', 'waline', 'artalk'];
23
+ for (var i = 0; i < homeCommentServices.length; i++) {
24
+ var key = homeCommentServices[i];
25
+ if (homeCmt[key]) {
26
+ page[key] = homeCmt[key];
27
+ }
28
+ }
29
+ }
30
+ }
8
31
 
9
32
  function layout_post_card(layout, post, content) {
10
33
  var el = '';
@@ -38,4 +61,7 @@ function layout_post_list(partial) {
38
61
  <%- layout_post_list(function(post){
39
62
  return partial('_partial/main/post_list/post_card', {post: post})
40
63
  }) %>
41
- <%- partial('_partial/main/post_list/paginator') %>
64
+ <%- partial('_partial/main/post_list/paginator') %>
65
+ <% if (homeCmt && homeCmt !== false && is_home_first_page()) { %>
66
+ <%- partial('_partial/comments/layout') %>
67
+ <% } %>
@@ -1,8 +1,10 @@
1
1
  <%# 笔记本列表页主体部分 %>
2
2
  <% for (const notebook of Object.values(theme.notebooks.tree)) { %>
3
3
  <div class="post-list wiki">
4
- <a class="post-card wiki<%= scrollreveal(' ') %>" href="<%= pretty_url(notebook.base_dir) %>">
4
+ <div class="post-card-wrap<%= scrollreveal(' ') %>">
5
+ <a class="post-card wiki" href="<%= pretty_url(notebook.base_dir) %>">
5
6
  <%- include('_partial/main/notebook/notebook_card', { notebook: notebook }) %>
6
7
  </a>
8
+ </div>
7
9
  </div>
8
10
  <% } %>
package/layout/notes.ejs CHANGED
@@ -1,12 +1,14 @@
1
1
  <%# 笔记列表页主体部分 %>
2
2
  <div class="post-list post">
3
3
  <% page.posts.each(post => { %>
4
+ <div class="post-card-wrap<%= scrollreveal(' ') %>">
4
5
  <a
5
- class="post-card<%= scrollreveal(' ') %> post"
6
+ class="post-card post"
6
7
  href="<%= pretty_url(post.link || post.path) %><%= page.activeTag ? `?tag=${page.activeTag}` : '' %>"
7
8
  >
8
9
  <%- include('_partial/main/notebook/note_card', { note: post }) %>
9
10
  </a>
11
+ </div>
10
12
  <% }) %>
11
13
  </div>
12
14
  <%- include('_partial/main/notebook/paginator') %>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.37.0",
3
+ "version": "1.38.0",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -42,6 +42,7 @@ hexo.extend.tag.register('poetry', require('./lib/poetry')(hexo), true)
42
42
  hexo.extend.tag.register('quot', require('./lib/quot')(hexo))
43
43
  hexo.extend.tag.register('blockquote', require('./lib/blockquote')(hexo), true)
44
44
  hexo.extend.tag.register('hashtag', require('./lib/hashtag')(hexo))
45
+ hexo.extend.tag.register('mbti', require('./lib/mbti')(hexo))
45
46
  hexo.extend.tag.register('okr', require('./lib/okr')(hexo), {ends: true})
46
47
  hexo.extend.tag.register('audio', require('./lib/audio')(hexo))
47
48
  hexo.extend.tag.register('video', require('./lib/video')(hexo))
@@ -0,0 +1,169 @@
1
+ /**
2
+ * mbti.js v1 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ *
4
+ * {% mbti INTJ-T 93-72-78-83-51 [url:https://...] [image:src] %}
5
+ *
6
+ * - type: 人格类型代码(如 INTJ-T / INTJ,大小写均可),决定标题与配色
7
+ * - scores: 五个百分比,用 - 分隔,顺序固定为 energy-mind-nature-tactics-identity
8
+ * - url: 档案链接(可选,url:https://...),支持完整 URL 或纯档案 ID
9
+ * - image: 标题上方横幅图片地址(可选)
10
+ */
11
+
12
+ 'use strict';
13
+
14
+ var TYPE_ROLES = {
15
+ INTJ: 'analyst',
16
+ INTP: 'analyst',
17
+ ENTJ: 'analyst',
18
+ ENTP: 'analyst',
19
+ INFJ: 'diplomat',
20
+ INFP: 'diplomat',
21
+ ENFJ: 'diplomat',
22
+ ENFP: 'diplomat',
23
+ ISTJ: 'sentinel',
24
+ ISFJ: 'sentinel',
25
+ ESTJ: 'sentinel',
26
+ ESFJ: 'sentinel',
27
+ ISTP: 'explorer',
28
+ ISFP: 'explorer',
29
+ ESTP: 'explorer',
30
+ ESFP: 'explorer'
31
+ };
32
+
33
+ var ROLE_COLORS = {
34
+ analyst: 'purple',
35
+ diplomat: 'green',
36
+ sentinel: 'blue',
37
+ explorer: 'yellow'
38
+ };
39
+
40
+ var TRAIT_KEYS = ['energy', 'mind', 'nature', 'tactics', 'identity'];
41
+
42
+ var TRAIT_COLORS = {
43
+ energy: '#2196f3',
44
+ mind: '#FFBD2B',
45
+ nature: '#3DC550',
46
+ tactics: '#9c27b0',
47
+ identity: '#F44336'
48
+ };
49
+
50
+ // 根据类型代码推导每个维度的偏向侧(trait 侧):E/I、N/S、T/F、J/P、A/T
51
+ function getTraitSides(typeCode) {
52
+ var code = typeCode.replace('-', '');
53
+ var sides = {};
54
+ sides.energy = code.charAt(0) === 'E' ? 'left' : 'right';
55
+ sides.mind = code.charAt(1) === 'N' ? 'left' : 'right';
56
+ sides.nature = code.charAt(2) === 'T' ? 'left' : 'right';
57
+ sides.tactics = code.charAt(3) === 'J' ? 'left' : 'right';
58
+ if (code.charAt(4) === 'A') {
59
+ sides.identity = 'left';
60
+ } else if (code.charAt(4) === 'T') {
61
+ sides.identity = 'right';
62
+ } else {
63
+ sides.identity = 'left';
64
+ console.warn('[mbti] identity variant missing, default to Assertive (-A): ' + typeCode);
65
+ }
66
+ return sides;
67
+ }
68
+
69
+ function clamp(value) {
70
+ value = parseInt(value, 10);
71
+ if (isNaN(value)) {
72
+ value = 0;
73
+ }
74
+ return Math.max(0, Math.min(100, value));
75
+ }
76
+
77
+ function alphaHex(hex, alpha) {
78
+ var r = parseInt(hex.slice(1, 3), 16);
79
+ var g = parseInt(hex.slice(3, 5), 16);
80
+ var b = parseInt(hex.slice(5, 7), 16);
81
+ return 'rgba(' + r + ',' + g + ',' + b + ',' + alpha + ')';
82
+ }
83
+
84
+ module.exports = ctx => function(args) {
85
+ args = ctx.args.map(args, ['image', 'url'], ['type', 'scores']);
86
+
87
+ var typeCode = String(args.type || '').trim().toUpperCase();
88
+ if (!typeCode) {
89
+ console.error('[mbti] missing personality type');
90
+ return '';
91
+ }
92
+ var typeMatch = typeCode.match(/^([A-Z]{4})/);
93
+ var typeKey = typeMatch ? typeMatch[1] : null;
94
+ var role = typeKey ? TYPE_ROLES[typeKey] : null;
95
+ if (!role) {
96
+ console.warn('[mbti] unknown personality type: ' + typeCode);
97
+ }
98
+ var themeColor = role ? ROLE_COLORS[role] : '';
99
+
100
+ var __ = (this && typeof this.__ === 'function') ? this.__ : ctx.theme.i18n.__(ctx.config.language);
101
+ var typeName = typeKey ? __('tag_plugins.mbti.types.' + typeKey) : '';
102
+ if (!typeName || typeName.indexOf('tag_plugins.mbti.types.') === 0) {
103
+ typeName = typeCode;
104
+ }
105
+
106
+ var scoreParts = String(args.scores || '').split('-');
107
+ var pcts = [];
108
+ for (var i = 0; i < TRAIT_KEYS.length; i++) {
109
+ pcts.push(clamp(scoreParts[i]));
110
+ }
111
+
112
+ var url = args.url ? String(args.url).trim() : '';
113
+ if (url && !/^https?:\/\//i.test(url)) {
114
+ url = 'https://www.16personalities.com/ch/' + encodeURIComponent('档案') + '/' + url;
115
+ }
116
+ if (url) {
117
+ url = url.replace(/"/g, '&quot;');
118
+ }
119
+
120
+ var image = args.image ? String(args.image).trim() : '';
121
+ if (image) {
122
+ image = image.replace(/"/g, '&quot;');
123
+ }
124
+
125
+ var traitSides = getTraitSides(typeCode);
126
+
127
+ var el = '<div class="tag-plugin colorful note mbti"';
128
+ if (themeColor) {
129
+ el += ' color="' + themeColor + '"';
130
+ }
131
+ el += '>';
132
+ if (image) {
133
+ el += '<img class="mbti-image" src="' + image + '" alt="" />';
134
+ }
135
+ var title = __('tag_plugins.mbti.title', typeCode, typeName);
136
+ el += '<div class="mbti-title">';
137
+ if (url) {
138
+ el += '<a class="mbti-title-link" href="' + url + '" target="_blank" rel="external nofollow noopener noreferrer">' + title + '</a>';
139
+ } else {
140
+ el += '<span class="mbti-title-text">' + title + '</span>';
141
+ }
142
+ el += '</div>';
143
+ el += '<div class="mbti-body">';
144
+ el += '<div class="mbti-traits">';
145
+ for (var j = 0; j < TRAIT_KEYS.length; j++) {
146
+ var key = TRAIT_KEYS[j];
147
+ var left = __('tag_plugins.mbti.traits.' + key + '.left');
148
+ var right = __('tag_plugins.mbti.traits.' + key + '.right');
149
+ var pct = pcts[j];
150
+ // 官网规则:trait 在左端时 reverse=true,圆点位置 = reverse ? 100-pct : pct,高亮侧由圆点位置决定
151
+ var reverse = traitSides[key] === 'left';
152
+ var position = reverse ? 100 - pct : pct;
153
+ var activeSide = position <= 50 ? 'left' : 'right';
154
+ // 填充从主导侧(trait 侧)开始:trait 在右时 fill 右对齐
155
+ var reversed = traitSides[key] === 'right' ? ' reversed' : '';
156
+ el += '<div class="mbti-trait' + reversed + '" style="--theme:' + TRAIT_COLORS[key] + '; --theme-a30:' + alphaHex(TRAIT_COLORS[key], 0.3) + '">';
157
+ el += '<div class="mbti-labels">';
158
+ el += '<span class="mbti-label left' + (activeSide === 'left' ? ' active' : '') + '">' + left + (activeSide === 'left' ? ' <span class="pct">' + pct + '%</span>' : '') + '</span>';
159
+ el += '<span class="mbti-label right' + (activeSide === 'right' ? ' active' : '') + '">' + (activeSide === 'right' ? '<span class="pct">' + pct + '%</span> ' : '') + right + '</span>';
160
+ el += '</div>';
161
+ // fill 从主导侧端点延伸到圆点位置(宽度与圆点互补),保证填充末端与圆点对齐
162
+ el += '<div class="mbti-progress"><div class="fill" style="width:' + (100 - pct) + '%"></div><span class="mbti-dot" style="left:' + position + '%"></span></div>';
163
+ el += '</div>';
164
+ }
165
+ el += '</div>';
166
+ el += '</div>';
167
+ el += '</div>';
168
+ return el;
169
+ };
@@ -2,6 +2,7 @@
2
2
  position: fixed
3
3
  display: flex
4
4
  text-align: center
5
+ border-radius: 8px
5
6
  bottom: 4rem
6
7
  left: 50%
7
8
  transform: translateX(-50%)
@@ -12,17 +13,15 @@
12
13
  box-shadow: 0 2px 8px rgba(black, .1), 0 4px 16px rgba(black, .1), 0 8px 32px rgba(black, .1)
13
14
  .headline
14
15
  font-size: $fsh2
15
- a, button
16
- border-radius: 6px
17
- background: var(--bg-a100)
16
+ margin-bottom: .5rem
17
+ a
18
18
  display: block
19
19
  color: inherit
20
- padding: 1rem
21
- font-size: 1rem
22
- button
23
- padding: 0
24
- width: 3rem
25
- margin-left: 1px
20
+ padding: .75rem
21
+ font-size: $fs-14
22
+
23
+ .canonical-tip.official
24
+ background-color: var(--bg-a100)
26
25
 
27
26
  .canonical-tip.unofficial
28
27
  background-color: hsl(5, 100%, 60%)
@@ -34,4 +33,4 @@
34
33
  50%
35
34
  background-color: hsl(5, 100%, 30%)
36
35
  100%
37
- background-color: hsl(5, 100%, 60%)
36
+ background-color: hsl(5, 100%, 60%)
@@ -14,7 +14,6 @@ p>code:not([class]),li>code:not([class])
14
14
  --theme: var(--text-p3)
15
15
  margin: var(--gap-p) 0
16
16
  border-radius: $border-card
17
- corner-shape: superellipse(1.2)
18
17
  overflow: hidden
19
18
  background: var(--block)
20
19
  font-family: $ff-codeblock
@@ -80,7 +79,6 @@ p>code:not([class]),li>code:not([class])
80
79
  .gist-file
81
80
  border: 1px solid var(--block-border)
82
81
  border-radius: $border-card
83
- corner-shape: superellipse(1.2)
84
82
  overflow: hidden
85
83
  .gist-data
86
84
  --bgColor-default: var(--block)
@@ -1,5 +1,6 @@
1
1
  *
2
2
  outline: none
3
+ corner-shape: $corner-shape
3
4
  html
4
5
  height: 100%
5
6
  width: 100%
@@ -9,7 +10,7 @@ html
9
10
  font-size: $fs-root
10
11
  -webkit-text-size-adjust: 100%
11
12
  -ms-text-size-adjust: 100%
12
- scroll-padding-top: 8px
13
+ scroll-padding-top: 0
13
14
  body
14
15
  background: var(--background)
15
16
  margin: 0
@@ -6,4 +6,12 @@ svg.icon
6
6
  overflow: hidden
7
7
 
8
8
  svg.active-icon
9
- color: var(--theme)
9
+ color: var(--theme)
10
+
11
+ // 隐藏的 SVG 渐变定义容器(配合 --item-grad 与 fill:var(--item-grad) 使用)
12
+ svg.grad-def
13
+ position: absolute
14
+ width: 0 !important
15
+ height: 0 !important
16
+ overflow: hidden
17
+ pointer-events: none
@@ -20,12 +20,19 @@
20
20
  margin-top: 0.5rem
21
21
 
22
22
  // card
23
- .post-list .post-card
23
+ .post-list .post-card-wrap
24
24
  display: block
25
25
  margin: 1rem 0
26
26
  border-radius: $border-card-l
27
- background: var(--card)
28
27
  hoverable-card()
28
+ &:hover
29
+ // 保留 hover 阴影变化,去掉位移:ScrollReveal 内联 transform 与合成层交互导致位移卡顿
30
+ transform: none !important
31
+
32
+ .post-list .post-card
33
+ display: block
34
+ border-radius: $border-card-l
35
+ background: var(--card)
29
36
  overflow: hidden
30
37
  z-index: 0
31
38
  position: relative
@@ -40,9 +47,16 @@
40
47
  // --blur-px: 0
41
48
  // --blur-height: 0
42
49
  --blur-sat: 200%
50
+ // 图片卡片 hover 封面放大:卡片本身不动,放大后的图片由圆角静态裁剪裁出圆角
51
+ .post-cover img, .cover img, .cover:before
52
+ transform: scale(1.05)
43
53
  img
44
54
  filter: brightness(var(--img-br)) saturate(var(--img-sat))
45
- trans1 all
55
+ // 封面放大用 0.5s 缓动,其余属性(亮度/饱和度)保持主题默认 0.2s
56
+ transition: all .2s ease-out, transform .5s ease-out
57
+ -moz-transition: all .2s ease-out, transform .5s ease-out
58
+ -webkit-transition: all .2s ease-out, transform .5s ease-out
59
+ -o-transition: all .2s ease-out, transform .5s ease-out
46
60
  .excerpt
47
61
  margin: 1rem 0
48
62
  @media screen and (max-width: $device-mobile)
@@ -116,20 +130,26 @@
116
130
  content: ''
117
131
  z-index 1
118
132
  position: absolute
119
- left: 0
120
- right: 0
121
- height: var(--blur-height)
122
- backdrop-filter: saturate(var(--blur-sat)) blur(var(--blur-px))
123
- -webkit-backdrop-filter: saturate(var(--blur-sat)) blur(var(--blur-px))
124
- trans1 all
125
- &[position=top]:before
126
133
  top: 0
127
- mask: linear-gradient(black, rgba(black, 0.75), transparent)
128
- -webkit-mask: linear-gradient(black, rgba(black, 0.75), transparent)
134
+ left: 0
135
+ width: 100%
136
+ height: 100%
137
+ // Chromium: corner-shape + overflow:hidden 的合成层裁剪与 backdrop-filter 不兼容,
138
+ // 渐变模糊改用同图模糊层(filter + mask)实现,观感与 backdrop-filter 等价
139
+ background-image: var(--cover-url)
140
+ background-size: cover
141
+ background-position: center
142
+ filter: brightness(var(--img-br)) saturate(var(--img-sat)) blur(var(--blur-px)) saturate(var(--blur-sat))
143
+ // 与封面 img 同步:缩放 0.5s 缓动,亮度/饱和度仍按 0.2s
144
+ transition: all .2s ease-out, transform .5s ease-out
145
+ -moz-transition: all .2s ease-out, transform .5s ease-out
146
+ -webkit-transition: all .2s ease-out, transform .5s ease-out
147
+ -o-transition: all .2s ease-out, transform .5s ease-out
148
+ mask: linear-gradient(black, rgba(black, 0.75) calc(var(--blur-height) * 0.5), transparent var(--blur-height))
149
+ -webkit-mask: linear-gradient(black, rgba(black, 0.75) calc(var(--blur-height) * 0.5), transparent var(--blur-height))
129
150
  &[position=bottom]:before
130
- bottom: 0
131
- mask: linear-gradient(transparent, rgba(black, 0.75), black)
132
- -webkit-mask: linear-gradient(transparent, rgba(black, 0.75), black)
151
+ mask: linear-gradient(to top, black, rgba(black, 0.75) calc(var(--blur-height) * 0.5), transparent var(--blur-height))
152
+ -webkit-mask: linear-gradient(to top, black, rgba(black, 0.75) calc(var(--blur-height) * 0.5), transparent var(--blur-height))
133
153
  .cover-info
134
154
  padding: 1.5rem 1rem
135
155
  position: absolute
@@ -211,4 +231,4 @@
211
231
 
212
232
  .post-list.archives
213
233
  @media screen and (max-width: $device-mobile)
214
- margin: 1rem 0
234
+ margin: 1rem 0
@@ -82,7 +82,6 @@
82
82
  .md-text.content
83
83
  p>img, .tag-plugin.image .image-bg
84
84
  border-radius: $border-image
85
- corner-shape: superellipse(1.2)
86
85
 
87
86
  // 链接样式
88
87
  li:not([class]) a:not([class])
@@ -91,10 +91,8 @@
91
91
 
92
92
  p>img, .tag-plugin.image .image-bg
93
93
  border-radius: $border-image-l
94
- corner-shape: superellipse(1.2)
95
94
  >img
96
95
  border-radius: $border-image-l
97
- corner-shape: superellipse(1.2)
98
96
 
99
97
 
100
98
  .l_body[type=story] .md-text.content>blockquote, .md-text.content .tag-plugin.blockquote
@@ -137,4 +135,4 @@
137
135
  .l_body[text-indent] .tag-plugin.tabs .tab-content .tab-pane>p:not([class])
138
136
  text-indent: 'calc(%s * 2)' % var(--fsp)
139
137
  a
140
- text-indent: 0
138
+ text-indent: 0
@@ -1,3 +1,6 @@
1
+ .article-banner-wrap
2
+ display: block
3
+
1
4
  .article.banner
2
5
  --text-banner: var(--text)
3
6
  background: var(--block)
@@ -48,22 +51,25 @@
48
51
  content: ''
49
52
  position: absolute
50
53
  z-index 0
54
+ top: 0
51
55
  left: 0
52
- right: 0
53
- backdrop-filter: saturate(var(--blur-sat)) blur(var(--blur-px))
54
- -webkit-backdrop-filter: saturate(var(--blur-sat)) blur(var(--blur-px))
56
+ width: 100%
57
+ height: 100%
58
+ // Chromium: corner-shape + overflow:hidden 的合成层裁剪与 backdrop-filter 不兼容,
59
+ // 渐变模糊改用同图模糊层(filter + mask)实现,观感与 backdrop-filter 等价
60
+ background-image: var(--bg-url)
61
+ background-size: cover
62
+ background-position: center
63
+ filter: blur(var(--blur-px)) saturate(var(--blur-sat))
55
64
  trans1 all
56
65
  opacity var(--blur-opacity)
66
+ pointer-events: none
57
67
  &:before
58
- top: 0
59
- height: var(--blur-height-top)
60
- mask: linear-gradient(black, rgba(black, 0.75), transparent)
61
- -webkit-mask: linear-gradient(black, rgba(black, 0.75), transparent)
68
+ mask: linear-gradient(black, rgba(black, 0.75) calc(var(--blur-height-top) * 0.5), transparent var(--blur-height-top))
69
+ -webkit-mask: linear-gradient(black, rgba(black, 0.75) calc(var(--blur-height-top) * 0.5), transparent var(--blur-height-top))
62
70
  &:after
63
- bottom: 0
64
- height: var(--blur-height-bottom)
65
- mask: linear-gradient(transparent, rgba(black, 0.75), black)
66
- -webkit-mask: linear-gradient(transparent, rgba(black, 0.75), black)
71
+ mask: linear-gradient(to top, black, rgba(black, 0.75) calc(var(--blur-height-bottom) * 0.5), transparent var(--blur-height-bottom))
72
+ -webkit-mask: linear-gradient(to top, black, rgba(black, 0.75) calc(var(--blur-height-bottom) * 0.5), transparent var(--blur-height-bottom))
67
73
  .top,.bottom
68
74
  z-index 1
69
75
 
@@ -3,7 +3,6 @@
3
3
  padding: 1rem
4
4
  background: var(--block)
5
5
  border-radius: $border-card-l
6
- corner-shape: superellipse(1.2)
7
6
  border: 1px solid var(--block-border)
8
7
  font-size: $fs-15
9
8
  line-height: 1.6
@@ -54,7 +54,7 @@
54
54
  a+a
55
55
  margin-left: 4px
56
56
 
57
- @media screen and (max-width: $device-mobile-iphone-max)
57
+ @media screen and (max-width: $device-mobile-max)
58
58
  .navbar.top
59
- top: 36px
60
-
59
+ top: 8px
60
+
@@ -24,6 +24,7 @@
24
24
  height: 48px
25
25
  flex-shrink: 0
26
26
  border-radius: 48px
27
+ corner-shape: round // 保持正圆(连续曲率会使正圆变成类方形曲线)
27
28
  overflow: hidden
28
29
  margin-right: 1rem
29
30
  div.bg
@@ -35,6 +36,7 @@
35
36
  width: "calc(100% - 2 * %s)" % @margin
36
37
  height: "calc(100% - 2 * %s)" % @margin
37
38
  border-radius: @width
39
+ corner-shape: round
38
40
  if hexo-config('style.animated_avatar.animate')
39
41
  div.bg
40
42
  trans1: opacity
@@ -83,3 +85,27 @@
83
85
  .hover
84
86
  transform: translateY(0)
85
87
  opacity: 1 !important
88
+
89
+ .wiki-home-wrap
90
+ margin: 1rem var(--gap-margin) .5rem
91
+
92
+ .wiki-home
93
+ display: flex
94
+ width: fit-content
95
+ align-items: center
96
+ padding: 6px 16px 6px 12px
97
+ border-radius: 32px
98
+ background: var(--bg-a50)
99
+ color: var(--text-p2)
100
+ font-size: $fs-13
101
+ trans2 color background
102
+ svg
103
+ height: 1em
104
+ width: auto
105
+ margin-right: 0.25rem
106
+ &:hover
107
+ color: var(--text-p1)
108
+ sidebar-light()
109
+
110
+ .l_left .wiki-home-wrap + .header
111
+ margin-top: 0.5rem
@@ -1,9 +1,9 @@
1
1
  .nav-area .menu
2
2
  width: 100%
3
- display: grid
4
- margin: 8px 0
5
- grid-template-columns: repeat(hexo-config('menubar.columns'), 1fr)
6
- grid-gap: 8px
3
+ display: flex
4
+ flex-direction: column
5
+ gap: 4px
6
+ margin: 0
7
7
  &::-webkit-scrollbar
8
8
  display: none
9
9
  &::-webkit-scrollbar-track-piece
@@ -14,41 +14,64 @@
14
14
  .nav-item
15
15
  box-sizing: border-box
16
16
  width: 100%
17
- min-height: 40px
17
+ min-height: 36px
18
18
  border-radius: $border-bar
19
- corner-shape: superellipse(1.2)
20
19
  font-size: $fs-15
21
- font-weight: 500
22
- color: var(--text-p3)
23
- text-align: center
24
- background: var(--bg-a50)
25
- trans1 background
20
+ color: var(--text-p2)
21
+ text-align: left
26
22
  position: relative
27
23
  display: flex
28
- flex-direction: column
24
+ flex-direction: row
25
+ font-weight: 500
29
26
  align-items: center
30
- justify-content: center
27
+ justify-content: flex-start
28
+ gap: 16px
29
+ padding: 0 16px
30
+ color: var(--text-p2)
31
+ // 菜单项主题色由配置内联提供(--item-theme),淡色变体在此基于它计算
32
+ --item-theme-light: x-theme-light()
31
33
  img,svg
32
- height: 28px
34
+ width: 1.5rem
35
+ height: 1.5rem
33
36
  object-fit: contain
34
- filter: grayscale(50%) brightness(0.8) opacity(0.5)
35
- trans1 all
37
+ opacity: 0.5
38
+ color: var(--text-p2)
36
39
  span
37
40
  text-overflow: ellipsis
38
41
  word-break: keep-all
39
- &.active, &:hover
42
+ &:hover
43
+ color: var(--text-p1)
44
+ sidebar-light()
45
+ img,svg
46
+ opacity: 1
47
+ > svg [fill="currentColor"]
48
+ fill: var(--item-grad)
49
+ > svg [stroke="currentColor"]
50
+ stroke: var(--item-grad)
51
+ &.active
40
52
  color: var(--text-p1)
41
- background: var(--bg-a100)
53
+ sidebar-light()
42
54
  img,svg
43
- filter: unset
44
- &.active:after
45
- content: ''
46
- position absolute
47
- width: 16px
48
- height: 2px
49
- left: 50%
50
- transform: translateX(-50%)
51
- border-radius: 2px
52
- bottom: 2px
53
- background: currentColor
54
-
55
+ opacity: 1
56
+ .active-dot
57
+ flex-shrink: 0
58
+ margin-left: auto
59
+ width: 8px
60
+ height: 8px
61
+ border-radius: 50%
62
+ corner-shape: round
63
+ background: x-theme-gradient()
64
+ > svg [fill="currentColor"]
65
+ fill: var(--item-grad)
66
+ > svg [stroke="currentColor"]
67
+ stroke: var(--item-grad)
68
+ // 未设置主题色的菜单项,激活/悬停时图标显示通用主题色
69
+ &:not(.themed)
70
+ &:hover, &.active
71
+ > svg
72
+ color: var(--theme)
73
+ // 设置了主题色的菜单项:主题色只作用于图标,文字保持标准色
74
+ &.themed
75
+ &:hover, &.active
76
+ > svg
77
+ color: var(--item-theme)
@@ -1,2 +1,2 @@
1
1
  .nav-area
2
- margin: 1rem var(--gap-margin) 0
2
+ margin: 1rem 0 2rem