@mintfolio/theme-verdant 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +66 -0
  3. package/THIRD_PARTY_NOTICES.md +11 -0
  4. package/assets/favicon.ico +0 -0
  5. package/assets/favicon.svg +9 -0
  6. package/assets/fonts/Inter-300.woff2 +0 -0
  7. package/assets/fonts/Inter-400.woff2 +0 -0
  8. package/assets/fonts/Inter-500.woff2 +0 -0
  9. package/assets/fonts/Inter-600.woff2 +0 -0
  10. package/assets/fonts/Inter-700.woff2 +0 -0
  11. package/assets/fonts/JetBrainsMono-400.woff2 +0 -0
  12. package/assets/fonts/JetBrainsMono-500.woff2 +0 -0
  13. package/assets/fonts/PlayfairDisplay-400.woff2 +0 -0
  14. package/assets/fonts/PlayfairDisplay-500.woff2 +0 -0
  15. package/assets/fonts/PlayfairDisplay-600.woff2 +0 -0
  16. package/assets/fonts/PlayfairDisplay-700.woff2 +0 -0
  17. package/components/base/Contact.astro +173 -0
  18. package/components/base/Hero.astro +228 -0
  19. package/components/base/Navigation.astro +288 -0
  20. package/components/base/Projects.astro +207 -0
  21. package/components/base/Skills.astro +158 -0
  22. package/components/blog/ArticleProse.astro +217 -0
  23. package/components/blog/CodeBlockEnhancer.astro +310 -0
  24. package/components/blog/PostCard.astro +98 -0
  25. package/components/blog/ProtectedArticle.astro +89 -0
  26. package/config/theme-verdant.config.mjs +74 -0
  27. package/layouts/Base.astro +460 -0
  28. package/lib/palettes.ts +10 -0
  29. package/licenses/Inter-OFL.txt +92 -0
  30. package/licenses/JetBrainsMono-OFL.txt +93 -0
  31. package/licenses/PlayfairDisplay-OFL.txt +191 -0
  32. package/package.json +68 -0
  33. package/pages/archive.astro +384 -0
  34. package/pages/home.astro +2049 -0
  35. package/pages/page.astro +434 -0
  36. package/pages/post.astro +1029 -0
  37. package/scripts/article.ts +42 -0
  38. package/scripts/articleOrigin.ts +31 -0
  39. package/scripts/articleTables.ts +15 -0
  40. package/scripts/blog.ts +26 -0
  41. package/scripts/codeBlocks.ts +172 -0
  42. package/scripts/hero.ts +173 -0
  43. package/scripts/home.ts +12 -0
  44. package/scripts/homePanels.ts +100 -0
  45. package/scripts/hotContent.ts +16 -0
  46. package/scripts/lifecycle.ts +3 -0
  47. package/scripts/lightbox.ts +14 -0
  48. package/scripts/postFilters.ts +101 -0
  49. package/scripts/postList.ts +132 -0
  50. package/scripts/progress.ts +29 -0
  51. package/scripts/protectedArticle.ts +49 -0
  52. package/scripts/protectedToc.ts +29 -0
  53. package/scripts/site.ts +145 -0
  54. package/scripts/tagFold.ts +61 -0
  55. package/scripts/theme.ts +102 -0
  56. package/scripts/toc.ts +149 -0
  57. package/settings.ts +21 -0
  58. package/styles/fonts.css +120 -0
  59. package/styles/global.css +146 -0
  60. package/styles/themes/happyhues/effects.css +62 -0
  61. package/styles/themes/happyhues/index.css +2 -0
  62. package/styles/themes/happyhues/theme.css +225 -0
  63. package/theme.mjs +60 -0
  64. package/utils/blogNavigation.ts +3 -0
  65. package/utils/homeReturnHint.ts +34 -0
  66. package/utils/storage.ts +16 -0
  67. package/utils/types.ts +8 -0
@@ -0,0 +1,2049 @@
1
+ ---
2
+ /** Verdant home renderer consumes only public site, post, and taxonomy data. */
3
+ import PostCard from '../components/blog/PostCard.astro';
4
+ import Base from '../layouts/Base.astro';
5
+ import Image from '@mintfolio/core/components/Image.astro';
6
+ import type { PageProps, HomePageData } from '@mintfolio/theme-api/astro';
7
+ import type { VerdantSettings } from '../settings';
8
+
9
+ interface Props extends PageProps<VerdantSettings, HomePageData> {}
10
+ const { theme, page } = Astro.props;
11
+ const posts = page.posts;
12
+ const HOME_PAGE_SIZE = theme.settings.homePageSize;
13
+ const latestActivityPosts = posts.slice(0, 3);
14
+ const projectCount = theme.site.projects.length;
15
+ const latestPost = posts[0] ?? null;
16
+ const profileAvatar = theme.site.profile.avatar;
17
+ const [allTags, allCategories] = await Promise.all([theme.taxonomy.tags(), theme.taxonomy.categories()]);
18
+ const hotContentPosts = theme.settings.home.hotContent.items
19
+ .map((item) => {
20
+ const post = posts.find((entry) => entry.id === item.postId);
21
+ return post ? { post, image: item.image } : null;
22
+ })
23
+ .filter((entry): entry is NonNullable<typeof entry> => entry !== null)
24
+ .slice(0, 3);
25
+ ---
26
+
27
+ <Base theme={theme} page={page}>
28
+ <!-- Hero Section -->
29
+ <section class="hero" id="hero" aria-label="欢迎区域">
30
+ <div class="hero-bg" aria-hidden="true">
31
+ <div class="hero-gradient"></div>
32
+ <div class="hero-pattern"></div>
33
+ <div class="hero-blob blob-1"></div>
34
+ <div class="hero-blob blob-2"></div>
35
+ <div class="hero-blob blob-3"></div>
36
+ </div>
37
+ <div class="hero-content">
38
+ <div class="hero-masthead" aria-hidden="true">
39
+ <span class="hero-wordmark">{theme.site.profile.name}<span class="wordmark-dot"></span></span>
40
+ <span>CODE · DESIGN · LIFE</span>
41
+ </div>
42
+ <div class="hero-shell">
43
+ <div class="hero-copy">
44
+ <span class="hero-kicker">Full-Stack Developer · Creative Coder</span>
45
+ <div class="hero-avatar-mobile" aria-hidden="true">
46
+ <Image src={profileAvatar} alt="" class="hero-avatar" width={108} height={108} />
47
+ </div>
48
+ <h1 class="hero-name">{theme.site.profile.name}</h1>
49
+ <p class="hero-tagline">{theme.site.profile.bio}</p>
50
+
51
+ <div class="hero-meta">
52
+ <span class="hero-location">{theme.site.profile.location}</span>
53
+ {latestPost && (
54
+ <span class="hero-update">
55
+ 最近更新 {new Date(latestPost.publishedAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'numeric', day: 'numeric' })}
56
+ </span>
57
+ )}
58
+ </div>
59
+
60
+ <div class="hero-highlights">
61
+ <span class="hero-chip">写代码</span>
62
+ <span class="hero-chip">做设计</span>
63
+ <span class="hero-chip">记灵感</span>
64
+ </div>
65
+
66
+ <div class="hero-actions">
67
+ <a href="#content" class="hero-btn primary" aria-label="浏览文章">
68
+ <svg class="hero-btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
69
+ <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"/>
70
+ <path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"/>
71
+ </svg>
72
+ <span class="hero-btn-label">浏览文章</span>
73
+ </a>
74
+ <a href={theme.urls.page('about')} class="hero-btn secondary" aria-label="关于我">
75
+ <svg class="hero-btn-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
76
+ <path d="M20 21a8 8 0 1 0-16 0"/>
77
+ <circle cx="12" cy="7" r="4"/>
78
+ </svg>
79
+ <span class="hero-btn-label">关于我</span>
80
+ </a>
81
+ <a href={theme.site.social[0]?.url} target="_blank" rel="noopener noreferrer" class="hero-btn secondary" aria-label="GitHub">
82
+ <svg class="hero-btn-icon" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
83
+ <path d="M12 0C5.37 0 0 5.49 0 12.26c0 5.42 3.44 10.02 8.2 11.64.6.12.82-.27.82-.59 0-.29-.01-1.07-.01-2.1-3.34.75-4.04-1.65-4.04-1.65-.55-1.42-1.34-1.8-1.34-1.8-1.09-.76.08-.75.08-.75 1.2.09 1.84 1.27 1.84 1.27 1.07 1.88 2.8 1.34 3.48 1.02.11-.8.42-1.35.77-1.66-2.67-.31-5.48-1.37-5.48-6.12 0-1.35.47-2.45 1.24-3.31-.12-.31-.54-1.57.12-3.26 0 0 1.01-.33 3.3 1.26a11.2 11.2 0 0 1 6 0c2.29-1.59 3.3-1.26 3.3-1.26.66 1.69.24 2.95.12 3.26.77.86 1.24 1.96 1.24 3.31 0 4.76-2.81 5.81-5.49 6.11.43.38.82 1.12.82 2.26 0 1.63-.01 2.95-.01 3.35 0 .33.22.72.83.59 4.76-1.62 8.2-6.22 8.2-11.64C24 5.49 18.63 0 12 0z"/>
84
+ </svg>
85
+ <span class="hero-btn-label">GitHub</span>
86
+ </a>
87
+ </div>
88
+ </div>
89
+
90
+ <div class="hero-panel">
91
+ <div class="hero-profile-card">
92
+ <span class="profile-sticker" aria-hidden="true">保持好奇 ✳</span>
93
+ <div class="hero-avatar-wrapper">
94
+ <Image src={profileAvatar} alt={theme.site.profile.name} class="hero-avatar" width={108} height={108} />
95
+ </div>
96
+ <p class="profile-note">一点代码,一点灵感。</p>
97
+ <p class="hero-signature">{theme.site.profile.signature}</p>
98
+ </div>
99
+
100
+ <div class="hero-metrics" aria-label="站点概览">
101
+ <div class="metric-card">
102
+ <span class="metric-value" data-countup={posts.length}>{posts.length}</span>
103
+ <span class="metric-label">已发布文章</span>
104
+ </div>
105
+ <div class="metric-card">
106
+ <span class="metric-value" data-countup={projectCount}>{projectCount}</span>
107
+ <span class="metric-label">长期项目</span>
108
+ </div>
109
+ <div class="metric-card">
110
+ <span class="metric-value" data-countup={allCategories.length}>{allCategories.length}</span>
111
+ <span class="metric-label">内容专题</span>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+
117
+ <div class="scroll-indicator" role="button" tabindex="0" aria-label="向下滚动查看内容">
118
+ <span class="scroll-mouse" aria-hidden="true">
119
+ <span class="scroll-dot"></span>
120
+ </span>
121
+ <span class="scroll-text">向下滚动</span>
122
+ </div>
123
+ </div>
124
+ </section>
125
+
126
+ <!-- Main Content -->
127
+ <section class="content-wrapper" id="content">
128
+ <button class="sidebar-drawer-toggle" id="sidebar-drawer-toggle" aria-label="打开侧边栏" aria-expanded="false">
129
+ <svg class="icon-menu" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18" aria-hidden="true">
130
+ <path d="M3 6h18M3 12h18M3 18h18"/>
131
+ </svg>
132
+ <svg class="icon-close" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="18" height="18" aria-hidden="true">
133
+ <path d="M18 6L6 18M6 6l12 12"/>
134
+ </svg>
135
+ </button>
136
+
137
+ <div class="sidebar-overlay" id="sidebar-overlay" aria-hidden="true"></div>
138
+
139
+ <div class="content-grid">
140
+ <!-- Left Sidebar -->
141
+ <aside class="sidebar sidebar-drawer" id="sidebar">
142
+ <div class="sidebar-card">
143
+ <div class="sidebar-header">
144
+ <div class="sidebar-avatar">
145
+ <Image src={profileAvatar} alt={theme.site.profile.name} width={80} height={80} />
146
+ </div>
147
+ <h2 class="sidebar-name">{theme.site.profile.name}</h2>
148
+ <p class="sidebar-bio">{theme.site.profile.bio}</p>
149
+ </div>
150
+
151
+ {theme.settings.sidebar.sections.contact && (
152
+ <div class="sidebar-section">
153
+ <h3 class="sidebar-section-title">联系方式</h3>
154
+ <div class="social-links">
155
+ {theme.site.social.map((link) => (
156
+ <a href={link.url} target="_blank" rel="noopener noreferrer" class="social-link" aria-label={link.platform}>
157
+ {link.icon === 'github' && (
158
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
159
+ <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
160
+ </svg>
161
+ )}
162
+ {link.icon === 'mail' && (
163
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
164
+ <path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
165
+ </svg>
166
+ )}
167
+ {link.icon === 'twitter' && (
168
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
169
+ <path d="M22.46 6c-.85.38-1.78.64-2.75.76 1-.6 1.76-1.55 2.12-2.68-.93.55-1.96.95-3.06 1.17-.88-.94-2.13-1.53-3.51-1.53-2.66 0-4.81 2.16-4.81 4.81 0 .38.04.75.13 1.1-4-.2-7.58-2.11-9.96-5.02-.42.72-.66 1.56-.66 2.46 0 1.68.85 3.16 2.14 4.02-.79-.02-1.53-.24-2.18-.6v.06c0 2.35 1.67 4.31 3.88 4.76-.4.1-.83.16-1.27.16-.31 0-.62-.03-.92-.08.63 1.96 2.45 3.39 4.61 3.43-1.69 1.32-3.83 2.1-6.15 2.1-.4 0-.8-.02-1.19-.07 2.19 1.4 4.78 2.22 7.57 2.22 9.07 0 14.02-7.52 14.02-14.02 0-.21 0-.42-.01-.63.96-.69 1.79-1.56 2.45-2.55z"/>
170
+ </svg>
171
+ )}
172
+ {link.icon === 'linkedin' && (
173
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
174
+ <path d="M19 3A2 2 0 0 1 21 5v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h14zM8.34 10.68H5.67V19h2.67v-8.32zM7 5.9a1.56 1.56 0 1 0 0 3.12A1.56 1.56 0 0 0 7 5.9zM18.33 14.22c0-2.5-1.33-3.66-3.1-3.66a2.67 2.67 0 0 0-2.42 1.34h-.03v-1.22H10.2V19h2.67v-4.12c0-1.08.2-2.13 1.54-2.13 1.31 0 1.33 1.22 1.33 2.2V19h2.67v-4.78z"/>
175
+ </svg>
176
+ )}
177
+ {link.icon === 'bilibili' && (
178
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
179
+ <path d="M7.4 4.5 9.8 7h4.4l2.4-2.5a1 1 0 1 1 1.45 1.38L17.2 7H19a3 3 0 0 1 3 3v7a3 3 0 0 1-3 3H5a3 3 0 0 1-3-3v-7a3 3 0 0 1 3-3h1.8L5.95 5.88A1 1 0 1 1 7.4 4.5ZM8 11a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm8 0a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3Zm-6.5 5h5a1 1 0 1 1 0 2h-5a1 1 0 0 1 0-2Z"/>
180
+ </svg>
181
+ )}
182
+ {link.icon === 'juejin' && (
183
+ <svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18">
184
+ <path d="M12 2 2.6 8.2l1.5 2.25L12 5.36l7.9 5.1 1.5-2.26L12 2Zm0 5.96L4.63 12.7l1.5 2.26L12 11.22l5.87 3.74 1.5-2.26L12 7.96Zm0 5.86-5.16 3.3L12 20.42l5.16-3.3L12 13.82Z"/>
185
+ </svg>
186
+ )}
187
+ {!['github', 'mail', 'twitter', 'linkedin', 'bilibili', 'juejin'].includes(link.icon) && (
188
+ <span>{link.platform.slice(0, 1).toUpperCase()}</span>
189
+ )}
190
+ </a>
191
+ ))}
192
+ </div>
193
+ </div>
194
+ )}
195
+
196
+ {theme.settings.sidebar.quote.enabled && (
197
+ <div class="sidebar-section">
198
+ <blockquote class="quote">
199
+ <p class="quote-text">"{theme.settings.sidebar.quote.text}"</p>
200
+ <cite class="quote-author">— {theme.settings.sidebar.quote.author}</cite>
201
+ </blockquote>
202
+ </div>
203
+ )}
204
+
205
+ {theme.settings.sidebar.sections.activity && (
206
+ <div class="sidebar-section">
207
+ <h3 class="sidebar-section-title">最近动态</h3>
208
+ <div class="activity-list">
209
+ {latestActivityPosts.map((post) => (
210
+ <div class="activity-item">
211
+ <span class="activity-dot"></span>
212
+ <div class="activity-content">
213
+ <p class="activity-text">
214
+ <a class="activity-link" href={post.url} data-article-link>{post.title}</a>
215
+ </p>
216
+ <time class="activity-time">{new Date(post.publishedAt).toLocaleDateString('zh-CN', { year: 'numeric', month: 'short', day: 'numeric' })}</time>
217
+ </div>
218
+ </div>
219
+ ))}
220
+ </div>
221
+ </div>
222
+ )}
223
+
224
+ {theme.settings.sidebar.sections.tools && (
225
+ <div class="sidebar-section">
226
+ <h3 class="sidebar-section-title">推荐工具</h3>
227
+ <div class="tools-list">
228
+ {theme.settings.sidebar.tools.map((tool) => (
229
+ <a href={tool.url} target="_blank" rel="noopener noreferrer" class="tool-item">
230
+ <span class="tool-name">{tool.name}</span>
231
+ <span class="tool-desc">{tool.description}</span>
232
+ </a>
233
+ ))}
234
+ </div>
235
+ </div>
236
+ )}
237
+ </div>
238
+ </aside>
239
+
240
+ <!-- Right: Blog Section -->
241
+ <main class="blog-section">
242
+ <button class="search-float-btn" id="search-float-btn" aria-label="打开搜索">
243
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
244
+ <circle cx="11" cy="11" r="8"/>
245
+ <path d="M21 21l-4.35-4.35"/>
246
+ </svg>
247
+ </button>
248
+
249
+ <dialog class="search-modal" id="search-modal" aria-label="文章搜索">
250
+ <div class="search-modal-panel">
251
+ <div class="search-modal-header">
252
+ <h3>文章筛选</h3>
253
+ <button class="search-close-btn" id="search-close-btn" aria-label="关闭搜索">×</button>
254
+ </div>
255
+ <div class="search-wrapper search-modal-input-wrap">
256
+ <svg class="search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
257
+ <circle cx="11" cy="11" r="8"/>
258
+ <path d="M21 21l-4.35-4.35"/>
259
+ </svg>
260
+ <input type="text" id="search-modal-input" class="search-input" placeholder="输入关键字搜索文章..." aria-label="搜索文章" />
261
+ </div>
262
+
263
+ <div class="search-filter-group">
264
+ <p class="search-filter-label" id="category-filter-label">分类</p>
265
+ <div class="category-filter" id="category-filter" role="radiogroup" aria-labelledby="category-filter-label">
266
+ <button class="category-btn active" role="radio" aria-checked="true" data-category="">全部分类</button>
267
+ {allCategories.map((category) => (
268
+ <button class="category-btn" role="radio" aria-checked="false" data-category={category.label}>{category.label}</button>
269
+ ))}
270
+ </div>
271
+ </div>
272
+
273
+ <div class="search-filter-group">
274
+ <p class="search-filter-label" id="tag-filter-label">标签</p>
275
+ <div class="tags-filter-block" data-max-rows="4">
276
+ <div class="tags-filter" id="tags-filter" role="radiogroup" aria-labelledby="tag-filter-label">
277
+ <button class="tag-btn active" role="radio" aria-checked="true" data-tag="">全部</button>
278
+ {allTags.map(tag => (
279
+ <button class="tag-btn" role="radio" aria-checked="false" data-tag={tag.label}>{tag.label}</button>
280
+ ))}
281
+ </div>
282
+ <button class="tags-filter-toggle" id="home-tags-filter-toggle" type="button" hidden aria-expanded="false">
283
+ 展开更多
284
+ </button>
285
+ </div>
286
+ </div>
287
+
288
+ <div class="search-actions">
289
+ <button class="search-apply-btn" id="search-apply-btn">到博客页搜索</button>
290
+ </div>
291
+ </div>
292
+ </dialog>
293
+
294
+ <div class="blog-header">
295
+ {theme.settings.home.hotContent.enabled && hotContentPosts.length > 0 && (
296
+ <section class="hot-content-section">
297
+ <div class="hot-content-header">
298
+ <h3><span class="section-spark" aria-hidden="true">✳</span> 值得一读</h3>
299
+ </div>
300
+ <div class="hot-content-carousel-wrapper">
301
+ <div class="hot-content-carousel" id="hot-content-carousel">
302
+ <div class="hot-content-list" id="hot-content-list">
303
+ {hotContentPosts.map(({ post, image }) => (
304
+ <a href={post.url} data-article-link class="hot-content-item" draggable="false">
305
+ <div class="hot-image-wrap">
306
+ <Image src={image} alt={post.title} loading="lazy" width={400} height={225} draggable="false" />
307
+ <span class="hot-overlay-title">{post.title}</span>
308
+ </div>
309
+ </a>
310
+ ))}
311
+ </div>
312
+ </div>
313
+ <div class="hot-scroll-indicator" id="hot-scroll-indicator" aria-label="滚动指示">
314
+ {hotContentPosts.map((_, index) => (
315
+ <span class={`hot-scroll-dot ${index === 0 ? 'active' : ''}`} data-index={index}></span>
316
+ ))}
317
+ </div>
318
+ </div>
319
+ </section>
320
+ )}
321
+
322
+ <div class="blog-title-row">
323
+ <div><p class="section-eyebrow">THE LATEST NOTES</p><h2 class="blog-title">最近在写<span class="title-dot" aria-hidden="true">.</span></h2></div>
324
+ <a href={theme.urls.archive()} class="view-all-link">查看全部 →</a>
325
+ </div>
326
+
327
+ <div class="blog-controls"></div>
328
+ </div>
329
+
330
+ <div id="posts-list" class="posts-list" data-page-size={HOME_PAGE_SIZE}>
331
+ {posts.map((post, index) => (
332
+ <PostCard post={post} index={index} pageSize={HOME_PAGE_SIZE} variant="home" />
333
+ ))}
334
+ </div>
335
+
336
+ <p id="no-results" class="no-results" style="display: none;">
337
+ 没有找到匹配的文章
338
+ </p>
339
+
340
+ <div class="load-more-wrap" id="load-more-wrap">
341
+ <button class="load-more-btn" id="load-more-btn">加载更多文章</button>
342
+ </div>
343
+ </main>
344
+ </div>
345
+ </section>
346
+
347
+ <!-- Footer -->
348
+ <footer class="footer">
349
+ <div class="footer-content">
350
+ <p class="copyright">© {new Date().getFullYear()} {theme.site.profile.name}. Built with Astro.</p>
351
+ <p class="site-links">
352
+ <a href={theme.urls.rss()} target="_blank" rel="noopener noreferrer">RSS 订阅</a>
353
+ <span>·</span>
354
+ <a href={theme.urls.sitemap()} target="_blank" rel="noopener noreferrer">网站树</a>
355
+ </p>
356
+ {theme.site.icp && (
357
+ <p class="icp">
358
+ <a href="https://beian.miit.gov.cn/" target="_blank" rel="noopener noreferrer">{theme.site.icp}</a>
359
+ </p>
360
+ )}
361
+ </div>
362
+ </footer>
363
+ </Base>
364
+
365
+ <style>
366
+ /* ===== HERO SECTION ===== */
367
+ .hero {
368
+ min-height: 100vh;
369
+ display: flex;
370
+ align-items: center;
371
+ justify-content: center;
372
+ position: fixed;
373
+ inset: 0;
374
+ overflow: hidden;
375
+ background: var(--color-bg);
376
+ z-index: 100;
377
+ transition: transform var(--transition-base), opacity var(--transition-base);
378
+ }
379
+
380
+ .hero.collapsed {
381
+ transform: translateY(-100%);
382
+ opacity: 0;
383
+ pointer-events: none;
384
+ }
385
+
386
+ .hero.collapsed *,
387
+ .hero.is-paused * {
388
+ animation-play-state: paused !important;
389
+ }
390
+
391
+ .hero-bg {
392
+ position: absolute;
393
+ inset: 0;
394
+ z-index: 0;
395
+ }
396
+
397
+ .hero-gradient {
398
+ position: absolute;
399
+ inset: 0;
400
+ background: linear-gradient(125deg, var(--color-bg) 40%, var(--color-play-soft) 100%);
401
+ }
402
+
403
+ .hero-pattern {
404
+ position: absolute;
405
+ inset: 0;
406
+ background-image: radial-gradient(var(--color-border) 1px, transparent 1px);
407
+ opacity: .32;
408
+ background-size: 28px 28px;
409
+ }
410
+
411
+ .hero-content {
412
+ position: relative;
413
+ z-index: 1;
414
+ max-width: 1120px;
415
+ width: min(94vw, 1120px);
416
+ border-radius: 30px;
417
+ animation: heroFadeIn 1s ease-out;
418
+ padding: clamp(1rem, 2vw, 2rem);
419
+ background: transparent;
420
+ border: none;
421
+ box-shadow: none;
422
+ }
423
+
424
+ @keyframes heroFadeIn {
425
+ from {
426
+ opacity: 0;
427
+ transform: translateY(40px);
428
+ }
429
+ to {
430
+ opacity: 1;
431
+ transform: translateY(0);
432
+ }
433
+ }
434
+
435
+ .hero-shell {
436
+ display: grid;
437
+ grid-template-columns: minmax(0, 1.35fr) minmax(280px, 0.9fr);
438
+ gap: clamp(1.25rem, 3vw, 2.4rem);
439
+ align-items: center;
440
+ }
441
+
442
+ .hero-copy {
443
+ text-align: left;
444
+ padding: clamp(0.45rem, 1vw, 0.8rem);
445
+ }
446
+
447
+ .hero-kicker {
448
+ display: inline-flex;
449
+ align-items: center;
450
+ gap: 0.45rem;
451
+ padding: 0.45rem 0.8rem;
452
+ border-radius: 999px;
453
+ text-transform: uppercase;
454
+ margin-bottom: 1rem;
455
+ background: var(--color-tag-bg);
456
+ color: var(--color-primary);
457
+ border: 1px solid var(--color-border);
458
+ font-size: .68rem;
459
+ letter-spacing: .06em;
460
+ }
461
+
462
+ .hero-avatar-mobile {
463
+ display: none;
464
+ }
465
+
466
+ .hero-avatar-wrapper {
467
+ border-radius: 50%;
468
+ overflow: hidden;
469
+ width: 124px;
470
+ height: 124px;
471
+ animation: none;
472
+ border: 4px solid var(--color-surface);
473
+ box-shadow: 0 0 0 2px var(--color-primary);
474
+ transform: rotate(-8deg);
475
+ }
476
+
477
+ @keyframes avatarPulse {
478
+ 0%, 100% { box-shadow: 0 8px 32px rgba(255, 216, 3, 0.25); }
479
+ 50% { box-shadow: 0 8px 48px rgba(255, 216, 3, 0.4); }
480
+ }
481
+
482
+ .hero-avatar {
483
+ width: 100%;
484
+ height: 100%;
485
+ object-fit: cover;
486
+ }
487
+
488
+ .hero-name {
489
+ font-family: var(--font-display);
490
+ font-weight: 700;
491
+ margin-bottom: 0.9rem;
492
+ font-size: clamp(3.5rem, 7.5vw, 6.5rem);
493
+ color: var(--color-primary);
494
+ letter-spacing: -0.05em;
495
+ line-height: 1.05;
496
+ max-width: 100%;
497
+ width: fit-content;
498
+ position: relative;
499
+ isolation: isolate;
500
+ }
501
+
502
+ .hero-tagline {
503
+ font-size: clamp(1.02rem, 1.8vw, 1.22rem);
504
+ color: var(--color-text);
505
+ margin-bottom: 1rem;
506
+ line-height: 1.75;
507
+ max-width: 34rem;
508
+ }
509
+
510
+ .hero-meta {
511
+ display: flex;
512
+ flex-wrap: wrap;
513
+ gap: 0.65rem;
514
+ margin-bottom: 1.15rem;
515
+ }
516
+
517
+ .hero-location,
518
+ .hero-update {
519
+ display: inline-flex;
520
+ align-items: center;
521
+ min-height: 2rem;
522
+ padding: 0.35rem 0.7rem;
523
+ border-radius: 999px;
524
+ background: color-mix(in srgb, var(--color-tag-bg) 72%, transparent);
525
+ border: 1px solid color-mix(in srgb, var(--color-border) 65%, transparent);
526
+ font-size: 0.82rem;
527
+ color: var(--color-text-muted);
528
+ }
529
+
530
+ .hero-highlights {
531
+ display: flex;
532
+ flex-wrap: wrap;
533
+ gap: 0.7rem;
534
+ margin-bottom: 1.4rem;
535
+ }
536
+
537
+ .hero-chip {
538
+ border-radius: 999px;
539
+ color: var(--color-text);
540
+ font-size: 0.82rem;
541
+ background: var(--color-play-soft);
542
+ border: 1px solid var(--color-border);
543
+ padding: .4rem .85rem;
544
+ }
545
+
546
+ .hero-actions {
547
+ display: flex;
548
+ flex-wrap: wrap;
549
+ gap: 1rem;
550
+ margin-bottom: 0;
551
+ }
552
+
553
+ .hero-btn {
554
+ display: inline-flex;
555
+ align-items: center;
556
+ justify-content: center;
557
+ gap: 0.6rem;
558
+ padding: 0.75rem 1.5rem;
559
+ border-radius: var(--radius-md);
560
+ font-size: 0.95rem;
561
+ font-weight: 500;
562
+ transition: all var(--transition-base);
563
+ text-decoration: none;
564
+ }
565
+
566
+ .hero-btn-icon {
567
+ width: 1rem;
568
+ height: 1rem;
569
+ flex-shrink: 0;
570
+ }
571
+
572
+ .hero-btn.primary {
573
+ background: var(--color-primary);
574
+ color: var(--color-on-primary);
575
+ border: 2px solid var(--color-primary);
576
+ box-shadow: 4px 4px 0 var(--color-accent-soft);
577
+ }
578
+
579
+ .hero-btn.primary:hover {
580
+ background: var(--color-primary);
581
+ transform: translateY(-2px);
582
+ box-shadow: 6px 6px 0 var(--color-accent-soft);
583
+ }
584
+
585
+ .hero-btn.secondary {
586
+ background: var(--color-surface);
587
+ color: var(--color-text);
588
+ border: 2px solid var(--color-border);
589
+ }
590
+
591
+ .hero-btn.secondary:hover {
592
+ border-color: var(--color-secondary);
593
+ color: var(--color-secondary);
594
+ }
595
+
596
+ .hero-panel {
597
+ display: grid;
598
+ gap: 1rem;
599
+ }
600
+
601
+ .hero-profile-card {
602
+ display: flex;
603
+ align-items: center;
604
+ border-radius: 24px;
605
+ position: relative;
606
+ flex-direction: column;
607
+ gap: .65rem;
608
+ padding: 2.5rem 1.5rem 1.75rem;
609
+ background: var(--color-play-soft);
610
+ border: 1.5px solid var(--color-text);
611
+ box-shadow: 8px 8px 0 var(--color-accent-soft);
612
+ transform: rotate(3deg);
613
+ min-height: 265px;
614
+ }
615
+
616
+ .hero-signature {
617
+ line-height: 1.7;
618
+ font-size: .78rem;
619
+ color: var(--color-text-muted);
620
+ }
621
+
622
+ .hero-metrics {
623
+ display: grid;
624
+ grid-template-columns: repeat(3, minmax(0, 1fr));
625
+ gap: 0.8rem;
626
+ }
627
+
628
+ .metric-card {
629
+ padding: 1rem 0.9rem;
630
+ border-radius: 20px;
631
+ background: var(--color-surface);
632
+ border: 1px solid var(--color-border);
633
+ box-shadow: var(--shadow-sm);
634
+ }
635
+
636
+ .metric-value {
637
+ display: block;
638
+ font-family: var(--font-display);
639
+ font-size: clamp(1.7rem, 2.6vw, 2.4rem);
640
+ font-weight: 700;
641
+ color: var(--color-text-headline);
642
+ line-height: 1;
643
+ margin-bottom: 0.45rem;
644
+ }
645
+
646
+ .metric-label {
647
+ display: block;
648
+ font-size: 0.78rem;
649
+ line-height: 1.5;
650
+ color: var(--color-text-muted);
651
+ letter-spacing: 0.03em;
652
+ }
653
+
654
+ .scroll-indicator {
655
+ display: flex;
656
+ flex-direction: column;
657
+ align-items: center;
658
+ gap: 0.75rem;
659
+ cursor: pointer;
660
+ animation: scrollBounce 2s ease-in-out infinite;
661
+ margin-top: 1.8rem;
662
+ }
663
+
664
+ @keyframes scrollBounce {
665
+ 0%, 100% { transform: translateY(0); }
666
+ 50% { transform: translateY(8px); }
667
+ }
668
+
669
+ .scroll-mouse {
670
+ width: 24px;
671
+ height: 40px;
672
+ border: 2px solid var(--color-text-muted);
673
+ border-radius: 12px;
674
+ position: relative;
675
+ }
676
+
677
+ .scroll-dot {
678
+ position: absolute;
679
+ top: 8px;
680
+ left: 50%;
681
+ transform: translateX(-50%);
682
+ width: 4px;
683
+ height: 8px;
684
+ background: var(--color-primary);
685
+ border-radius: 2px;
686
+ animation: scrollDot 1.5s ease-in-out infinite;
687
+ }
688
+
689
+ @keyframes scrollDot {
690
+ 0%, 100% { top: 8px; opacity: 1; }
691
+ 50% { top: 20px; opacity: 0.3; }
692
+ }
693
+
694
+ .scroll-text {
695
+ font-size: 0.75rem;
696
+ color: var(--color-text-muted);
697
+ letter-spacing: 0.1em;
698
+ text-transform: uppercase;
699
+ }
700
+
701
+ /* ===== CONTENT WRAPPER ===== */
702
+ .content-wrapper {
703
+ padding: var(--section-padding);
704
+ min-height: 100vh;
705
+ position: relative;
706
+ margin-top: 100vh;
707
+ transition: margin-top var(--transition-base);
708
+ background: radial-gradient(ellipse at 0 0, var(--color-play-soft), transparent 550px), var(--color-bg);
709
+ }
710
+
711
+ .content-wrapper.hero-collapsed {
712
+ margin-top: 0;
713
+ }
714
+
715
+ .sidebar-drawer-toggle {
716
+ display: none;
717
+ }
718
+
719
+ .sidebar-drawer-toggle.visible {
720
+ opacity: 1;
721
+ pointer-events: auto;
722
+ }
723
+
724
+ .sidebar-overlay {
725
+ display: none;
726
+ }
727
+
728
+ .content-grid {
729
+ max-width: var(--max-width);
730
+ margin: 0 auto;
731
+ display: grid;
732
+ grid-template-columns: 1fr;
733
+ align-items: start;
734
+ gap: 3rem;
735
+ }
736
+
737
+ @media (min-width: 900px) {
738
+ .content-grid {
739
+ grid-template-columns: 300px 1fr;
740
+ }
741
+ }
742
+
743
+ /* ===== SIDEBAR ===== */
744
+ .sidebar {
745
+ animation: sidebarSlideIn 0.8s ease-out;
746
+ }
747
+
748
+ @keyframes sidebarSlideIn {
749
+ from {
750
+ opacity: 0;
751
+ transform: translateX(-30px);
752
+ }
753
+ to {
754
+ opacity: 1;
755
+ transform: translateX(0);
756
+ }
757
+ }
758
+
759
+ .sidebar-card {
760
+ background: var(--color-surface);
761
+ border-radius: var(--radius-lg);
762
+ overflow: hidden;
763
+ position: sticky;
764
+ top: 2rem;
765
+ border: 1px solid var(--color-border);
766
+ box-shadow: var(--shadow-offset);
767
+ }
768
+
769
+ @media (max-width: 899px) {
770
+ .sidebar-drawer-toggle {
771
+ display: flex;
772
+ align-items: center;
773
+ justify-content: center;
774
+ width: 48px;
775
+ height: 48px;
776
+ border-radius: var(--radius-full);
777
+ border: 1px solid var(--color-border);
778
+ background: color-mix(in srgb, var(--color-surface) 84%, rgba(255, 255, 255, 0.35));
779
+ color: var(--color-text);
780
+ position: fixed;
781
+ left: 0.9rem;
782
+ top: calc(env(safe-area-inset-top, 0px) + 0.9rem);
783
+ transform: translateY(-8px) scale(0.96);
784
+ cursor: pointer;
785
+ z-index: 246;
786
+ box-shadow:
787
+ 0 14px 28px rgba(15, 23, 42, 0.12),
788
+ inset 0 1px 0 rgba(255, 255, 255, 0.24);
789
+ backdrop-filter: blur(14px) saturate(130%);
790
+ -webkit-backdrop-filter: blur(14px) saturate(130%);
791
+ transition:
792
+ transform var(--transition-base),
793
+ opacity var(--transition-fast),
794
+ box-shadow var(--transition-fast),
795
+ background-color var(--transition-fast),
796
+ color var(--transition-fast),
797
+ border-color var(--transition-fast);
798
+ opacity: 0;
799
+ pointer-events: none;
800
+ }
801
+
802
+ .sidebar-drawer-toggle .icon-menu,
803
+ .sidebar-drawer-toggle .icon-close {
804
+ position: absolute;
805
+ transition:
806
+ transform 220ms ease,
807
+ opacity 180ms ease;
808
+ }
809
+
810
+ .sidebar-drawer-toggle .icon-close {
811
+ opacity: 0;
812
+ transform: scale(0.7) rotate(-90deg);
813
+ }
814
+
815
+ .sidebar-drawer-toggle:hover {
816
+ color: var(--color-secondary);
817
+ box-shadow: var(--shadow-lg);
818
+ }
819
+
820
+ .sidebar-drawer-toggle.open {
821
+ transform: translateY(0) scale(1);
822
+ background: var(--color-secondary);
823
+ color: var(--color-bg);
824
+ border-color: transparent;
825
+ box-shadow:
826
+ 0 18px 36px rgba(15, 23, 42, 0.18),
827
+ 0 0 0 6px color-mix(in srgb, var(--color-secondary) 16%, transparent);
828
+ }
829
+
830
+ .sidebar-drawer-toggle.open,
831
+ .sidebar-drawer-toggle.visible {
832
+ opacity: 1;
833
+ pointer-events: auto;
834
+ }
835
+
836
+ .sidebar-drawer-toggle.visible {
837
+ transform: translateY(0) scale(1);
838
+ }
839
+
840
+ .sidebar-drawer-toggle.open .icon-menu {
841
+ opacity: 0;
842
+ transform: scale(0.7) rotate(90deg);
843
+ }
844
+
845
+ .sidebar-drawer-toggle.open .icon-close {
846
+ opacity: 1;
847
+ transform: scale(1) rotate(0deg);
848
+ }
849
+
850
+ .sidebar-overlay {
851
+ display: block;
852
+ position: fixed;
853
+ inset: 0;
854
+ background: rgba(0, 0, 0, 0.35);
855
+ backdrop-filter: blur(2px);
856
+ -webkit-backdrop-filter: blur(2px);
857
+ opacity: 0;
858
+ pointer-events: none;
859
+ transition: opacity var(--transition-fast);
860
+ z-index: 235;
861
+ }
862
+
863
+ .sidebar-overlay.open {
864
+ opacity: 1;
865
+ pointer-events: auto;
866
+ }
867
+
868
+ .sidebar-drawer {
869
+ position: fixed;
870
+ left: 0;
871
+ top: 0;
872
+ bottom: 0;
873
+ width: min(84vw, 340px);
874
+ padding: calc(env(safe-area-inset-top, 0px) + 4.2rem) 0.75rem 1rem 1rem;
875
+ transform: translateX(calc(-100% - 24px)) scale(0.98);
876
+ transform-origin: left center;
877
+ opacity: 0;
878
+ visibility: hidden;
879
+ transition:
880
+ transform 320ms cubic-bezier(0.22, 1, 0.36, 1),
881
+ opacity 220ms ease,
882
+ visibility 220ms ease;
883
+ z-index: 240;
884
+ overflow: auto;
885
+ animation: none;
886
+ }
887
+
888
+ .sidebar-drawer.open {
889
+ transform: translateX(0) scale(1);
890
+ opacity: 1;
891
+ visibility: visible;
892
+ }
893
+
894
+ .sidebar-drawer .sidebar-card {
895
+ position: static;
896
+ min-height: 100%;
897
+ border-radius: 1.75rem;
898
+ border: 1px solid color-mix(in srgb, var(--color-border) 72%, transparent);
899
+ background:
900
+ linear-gradient(180deg, color-mix(in srgb, var(--color-surface) 92%, rgba(255, 255, 255, 0.2)) 0%, color-mix(in srgb, var(--color-surface) 100%, transparent) 100%);
901
+ box-shadow:
902
+ 0 26px 56px rgba(15, 23, 42, 0.18),
903
+ inset 0 1px 0 rgba(255, 255, 255, 0.24);
904
+ overflow: hidden;
905
+ }
906
+
907
+ .sidebar-card {
908
+ position: static;
909
+ }
910
+
911
+ .sidebar {
912
+ animation: none;
913
+ }
914
+
915
+ :global(body.sidebar-drawer-open) #ui-float-right {
916
+ opacity: 0 !important;
917
+ pointer-events: none !important;
918
+ transform: translateX(16px) !important;
919
+ }
920
+ }
921
+
922
+ .sidebar-header {
923
+ padding: 2rem;
924
+ text-align: center;
925
+ border-bottom: 1px solid var(--color-border);
926
+ background: linear-gradient(155deg, var(--color-play-soft), var(--color-accent-soft));
927
+ }
928
+
929
+ .sidebar-avatar {
930
+ width: 80px;
931
+ height: 80px;
932
+ margin: 0 auto 1rem;
933
+ border-radius: 50%;
934
+ overflow: hidden;
935
+ border: 3px solid var(--color-primary);
936
+ }
937
+
938
+ .sidebar-avatar img {
939
+ width: 100%;
940
+ height: 100%;
941
+ object-fit: cover;
942
+ }
943
+
944
+ .sidebar-name {
945
+ font-family: var(--font-display);
946
+ font-size: 1.25rem;
947
+ font-weight: 600;
948
+ color: var(--color-text-headline);
949
+ margin-bottom: 0.5rem;
950
+ }
951
+
952
+ .sidebar-bio {
953
+ font-size: 0.85rem;
954
+ color: var(--color-text-muted);
955
+ line-height: 1.5;
956
+ }
957
+
958
+ .sidebar-section {
959
+ padding: 1.5rem 2rem;
960
+ border-bottom: 1px solid var(--color-border);
961
+ }
962
+
963
+ .sidebar-section:last-child {
964
+ border-bottom: none;
965
+ }
966
+
967
+ .sidebar-section-title {
968
+ font-size: 0.75rem;
969
+ font-weight: 600;
970
+ color: var(--color-text-muted);
971
+ text-transform: uppercase;
972
+ letter-spacing: 0.1em;
973
+ margin-bottom: 1rem;
974
+ }
975
+
976
+ .social-links {
977
+ display: flex;
978
+ justify-content: center;
979
+ gap: 0.75rem;
980
+ }
981
+
982
+ .social-link {
983
+ display: flex;
984
+ align-items: center;
985
+ justify-content: center;
986
+ width: 36px;
987
+ height: 36px;
988
+ border-radius: var(--radius-full);
989
+ background: var(--color-bg-alt);
990
+ color: var(--color-text);
991
+ transition: all var(--transition-base);
992
+ }
993
+
994
+ .social-link:hover {
995
+ background: var(--color-primary);
996
+ color: var(--color-on-primary);
997
+ transform: translateY(-2px);
998
+ }
999
+
1000
+ .activity-list {
1001
+ display: flex;
1002
+ flex-direction: column;
1003
+ gap: 1rem;
1004
+ }
1005
+
1006
+ .activity-item {
1007
+ display: flex;
1008
+ gap: 0.75rem;
1009
+ align-items: flex-start;
1010
+ }
1011
+
1012
+ .activity-dot {
1013
+ width: 8px;
1014
+ height: 8px;
1015
+ border-radius: 50%;
1016
+ background: var(--color-primary);
1017
+ margin-top: 0.375rem;
1018
+ flex-shrink: 0;
1019
+ }
1020
+
1021
+ .activity-content {
1022
+ flex: 1;
1023
+ }
1024
+
1025
+ .activity-text {
1026
+ font-size: 0.8rem;
1027
+ color: var(--color-text);
1028
+ margin-bottom: 0.125rem;
1029
+ line-height: 1.4;
1030
+ }
1031
+
1032
+ .activity-link {
1033
+ color: inherit;
1034
+ text-decoration: none;
1035
+ transition: color var(--transition-fast);
1036
+ }
1037
+
1038
+ .activity-link:hover {
1039
+ color: var(--color-secondary);
1040
+ }
1041
+
1042
+ .activity-time {
1043
+ font-size: 0.7rem;
1044
+ color: var(--color-text-muted);
1045
+ font-family: var(--font-mono);
1046
+ }
1047
+
1048
+ .tools-list {
1049
+ display: flex;
1050
+ flex-direction: column;
1051
+ gap: 0.5rem;
1052
+ }
1053
+
1054
+ .tool-item {
1055
+ display: flex;
1056
+ justify-content: space-between;
1057
+ align-items: center;
1058
+ padding: 0.5rem 0.75rem;
1059
+ border-radius: var(--radius-sm);
1060
+ background: var(--color-bg-alt);
1061
+ text-decoration: none;
1062
+ transition: all var(--transition-fast);
1063
+ }
1064
+
1065
+ .tool-item:hover {
1066
+ background: var(--color-tag-bg);
1067
+ transform: translateX(4px);
1068
+ }
1069
+
1070
+ .tool-name {
1071
+ font-size: 0.8rem;
1072
+ font-weight: 500;
1073
+ color: var(--color-text);
1074
+ }
1075
+
1076
+ .tool-desc {
1077
+ font-size: 0.7rem;
1078
+ color: var(--color-text-muted);
1079
+ }
1080
+
1081
+ .quote {
1082
+ border-left: 3px solid var(--color-primary);
1083
+ padding-left: 1rem;
1084
+ margin: 0;
1085
+ }
1086
+
1087
+ .quote-text {
1088
+ font-family: var(--font-display);
1089
+ font-size: 0.9rem;
1090
+ color: var(--color-text);
1091
+ font-style: italic;
1092
+ line-height: 1.6;
1093
+ margin-bottom: 0.5rem;
1094
+ }
1095
+
1096
+ .quote-author {
1097
+ font-size: 0.75rem;
1098
+ color: var(--color-text-muted);
1099
+ font-style: normal;
1100
+ }
1101
+
1102
+ /* ===== BLOG SECTION ===== */
1103
+ .blog-section {
1104
+ min-height: 50vh;
1105
+ }
1106
+
1107
+ .blog-header {
1108
+ margin-bottom: 2rem;
1109
+ }
1110
+
1111
+ .blog-title-row {
1112
+ display: flex;
1113
+ justify-content: space-between;
1114
+ align-items: center;
1115
+ margin-top: 2rem;
1116
+ margin-bottom: 1.15rem;
1117
+ }
1118
+
1119
+ .blog-title {
1120
+ font-family: var(--font-display);
1121
+ font-weight: 700;
1122
+ color: var(--color-text-headline);
1123
+ font-size: 1.7rem;
1124
+ }
1125
+
1126
+ .view-all-link {
1127
+ font-size: 0.875rem;
1128
+ color: var(--color-text-muted);
1129
+ text-decoration: none;
1130
+ transition: color var(--transition-fast);
1131
+ background: var(--color-surface);
1132
+ border: 1px solid var(--color-border);
1133
+ padding: .4rem .8rem;
1134
+ border-radius: var(--radius-full);
1135
+ }
1136
+
1137
+ .view-all-link:hover {
1138
+ color: var(--color-secondary);
1139
+ }
1140
+
1141
+ .blog-controls {
1142
+ min-height: 0;
1143
+ }
1144
+
1145
+ .search-float-btn {
1146
+ position: fixed;
1147
+ right: 2rem;
1148
+ top: 2rem;
1149
+ width: 44px;
1150
+ height: 44px;
1151
+ border-radius: 50%;
1152
+ display: flex;
1153
+ align-items: center;
1154
+ justify-content: center;
1155
+ border: 1px solid var(--color-border);
1156
+ background: var(--color-surface);
1157
+ color: var(--color-text);
1158
+ cursor: pointer;
1159
+ box-shadow: var(--shadow-md);
1160
+ transition:
1161
+ transform var(--transition-fast),
1162
+ scale var(--transition-fast),
1163
+ opacity var(--transition-fast),
1164
+ color var(--transition-fast),
1165
+ box-shadow var(--transition-fast);
1166
+ z-index: 190;
1167
+ opacity: 0;
1168
+ transform: translateX(20px);
1169
+ pointer-events: none;
1170
+ }
1171
+
1172
+ .search-float-btn.visible {
1173
+ opacity: 1;
1174
+ transform: translateX(0);
1175
+ pointer-events: auto;
1176
+ }
1177
+
1178
+ .search-float-btn svg {
1179
+ width: 18px;
1180
+ height: 18px;
1181
+ }
1182
+
1183
+ .search-float-btn:hover {
1184
+ color: var(--color-secondary);
1185
+ scale: 1.05;
1186
+ box-shadow: var(--shadow-lg);
1187
+ }
1188
+
1189
+ .search-modal {
1190
+ margin: 0;
1191
+ border: 0;
1192
+ width: 100%;
1193
+ height: 100%;
1194
+ max-width: none;
1195
+ max-height: none;
1196
+ color: var(--color-text);
1197
+ position: fixed;
1198
+ inset: 0;
1199
+ background: rgba(0, 0, 0, 0.35);
1200
+ backdrop-filter: blur(2px);
1201
+ -webkit-backdrop-filter: blur(2px);
1202
+ display: none;
1203
+ align-items: flex-start;
1204
+ justify-content: flex-end;
1205
+ padding: 5.5rem 2rem 1rem;
1206
+ opacity: 0;
1207
+ visibility: hidden;
1208
+ pointer-events: none;
1209
+ transition: opacity var(--transition-fast), visibility var(--transition-fast);
1210
+ z-index: 70;
1211
+ }
1212
+
1213
+ .search-modal[open] {
1214
+ display: flex;
1215
+ opacity: 1;
1216
+ visibility: visible;
1217
+ pointer-events: auto;
1218
+ }
1219
+
1220
+ @starting-style {
1221
+ .search-modal[open] {
1222
+ opacity: 0;
1223
+ }
1224
+ }
1225
+
1226
+ .search-modal-panel {
1227
+ width: min(680px, calc(100vw - 4rem));
1228
+ background: color-mix(in srgb, var(--color-surface) 85%, transparent);
1229
+ border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
1230
+ border-radius: var(--radius-lg);
1231
+ padding: 1rem;
1232
+ box-shadow: var(--shadow-lg);
1233
+ max-height: calc(100vh - 7rem);
1234
+ overflow: auto;
1235
+ }
1236
+
1237
+ .search-modal-header {
1238
+ display: flex;
1239
+ align-items: center;
1240
+ justify-content: space-between;
1241
+ margin-bottom: 0.8rem;
1242
+ }
1243
+
1244
+ .search-modal-header h3 {
1245
+ font-size: 0.95rem;
1246
+ color: var(--color-text);
1247
+ }
1248
+
1249
+ .search-close-btn {
1250
+ width: 28px;
1251
+ height: 28px;
1252
+ border-radius: 50%;
1253
+ border: 1px solid var(--color-border);
1254
+ background: var(--color-bg-alt);
1255
+ color: var(--color-text-muted);
1256
+ cursor: pointer;
1257
+ font-size: 1rem;
1258
+ line-height: 1;
1259
+ transition: color var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
1260
+ touch-action: manipulation;
1261
+ }
1262
+
1263
+ .search-close-btn:hover {
1264
+ color: var(--color-secondary);
1265
+ border-color: var(--color-secondary);
1266
+ }
1267
+
1268
+ @media (prefers-reduced-motion: no-preference) {
1269
+ .search-close-btn:active {
1270
+ transform: scale(0.96);
1271
+ }
1272
+ }
1273
+
1274
+ .search-modal-input-wrap {
1275
+ max-width: 100%;
1276
+ }
1277
+
1278
+ .search-filter-group {
1279
+ margin-top: 0.85rem;
1280
+ }
1281
+
1282
+ .search-filter-label {
1283
+ font-size: 0.76rem;
1284
+ color: var(--color-text-muted);
1285
+ margin-bottom: 0.45rem;
1286
+ }
1287
+
1288
+ .search-actions {
1289
+ display: flex;
1290
+ justify-content: flex-end;
1291
+ margin-top: 0.9rem;
1292
+ }
1293
+
1294
+ .search-apply-btn {
1295
+ padding: 0.5rem 0.9rem;
1296
+ border-radius: var(--radius-md);
1297
+ border: 1px solid var(--color-secondary);
1298
+ background: var(--color-secondary);
1299
+ color: var(--color-bg);
1300
+ font-size: 0.8rem;
1301
+ font-weight: 600;
1302
+ cursor: pointer;
1303
+ transition: all var(--transition-fast);
1304
+ }
1305
+
1306
+ .search-apply-btn:hover {
1307
+ transform: translateY(-1px);
1308
+ opacity: 0.92;
1309
+ }
1310
+
1311
+ .hot-content-section {
1312
+ margin-bottom: 1.4rem;
1313
+ box-shadow: none;
1314
+ padding: 1.1rem;
1315
+ border: 1px solid var(--color-border);
1316
+ background: var(--color-accent-soft);
1317
+ border-radius: var(--radius-lg);
1318
+ }
1319
+
1320
+ .hot-content-header {
1321
+ display: flex;
1322
+ align-items: baseline;
1323
+ justify-content: flex-start;
1324
+ margin-bottom: 0.65rem;
1325
+ }
1326
+
1327
+ .hot-content-header h3 {
1328
+ color: var(--color-text);
1329
+ font-size: .9rem;
1330
+ font-weight: 650;
1331
+ }
1332
+
1333
+ .hot-content-list {
1334
+ display: grid;
1335
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1336
+ gap: 0.8rem;
1337
+ }
1338
+
1339
+ .hot-content-carousel {
1340
+ overflow: visible;
1341
+ }
1342
+
1343
+ .hot-content-list::-webkit-scrollbar {
1344
+ display: none;
1345
+ }
1346
+
1347
+ .hot-content-item {
1348
+ display: block;
1349
+ border: 1px solid var(--color-border);
1350
+ border-radius: var(--radius-sm);
1351
+ text-decoration: none;
1352
+ background: var(--color-bg-alt);
1353
+ overflow: hidden;
1354
+ transition: all var(--transition-fast);
1355
+ }
1356
+
1357
+ .hot-content-item:hover {
1358
+ border-color: var(--color-secondary);
1359
+ transform: translateY(-1px);
1360
+ }
1361
+
1362
+ .hot-image-wrap {
1363
+ position: relative;
1364
+ width: 100%;
1365
+ aspect-ratio: 16 / 9;
1366
+ background: var(--color-surface);
1367
+ overflow: hidden;
1368
+ }
1369
+
1370
+ .hot-image-wrap img {
1371
+ width: 100%;
1372
+ height: 100%;
1373
+ object-fit: cover;
1374
+ display: block;
1375
+ }
1376
+
1377
+ .hot-overlay-title {
1378
+ position: absolute;
1379
+ left: 0;
1380
+ right: 0;
1381
+ bottom: 0;
1382
+ padding: 0.65rem 0.7rem;
1383
+ font-size: 0.82rem;
1384
+ line-height: 1.35;
1385
+ color: #fff;
1386
+ background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.82) 78%);
1387
+ opacity: 0;
1388
+ transform: translateY(8px);
1389
+ transition: opacity var(--transition-fast), transform var(--transition-fast);
1390
+ pointer-events: none;
1391
+ }
1392
+
1393
+ .hot-content-item:hover .hot-overlay-title {
1394
+ opacity: 1;
1395
+ transform: translateY(0);
1396
+ }
1397
+
1398
+ .controls-right {
1399
+ display: flex;
1400
+ flex-wrap: wrap;
1401
+ align-items: center;
1402
+ gap: 0.75rem;
1403
+ width: auto;
1404
+ }
1405
+
1406
+ .category-filter {
1407
+ display: flex;
1408
+ flex-wrap: wrap;
1409
+ gap: 0.5rem;
1410
+ }
1411
+
1412
+ .category-btn {
1413
+ padding: 0.35rem 0.75rem;
1414
+ border: 1px solid var(--color-border);
1415
+ border-radius: var(--radius-full);
1416
+ background: var(--color-bg-alt);
1417
+ color: var(--color-text-muted);
1418
+ font-size: 0.78rem;
1419
+ cursor: pointer;
1420
+ transition: all var(--transition-fast);
1421
+ }
1422
+
1423
+ .category-btn:hover {
1424
+ border-color: var(--color-secondary);
1425
+ color: var(--color-text);
1426
+ }
1427
+
1428
+ .category-btn.active {
1429
+ background: var(--color-primary);
1430
+ border-color: var(--color-primary);
1431
+ color: var(--color-on-primary);
1432
+ }
1433
+
1434
+ @media (min-width: 600px) {
1435
+ .blog-controls {
1436
+ min-height: 0;
1437
+ }
1438
+ }
1439
+
1440
+ .search-wrapper {
1441
+ position: relative;
1442
+ width: 100%;
1443
+ max-width: 280px;
1444
+ }
1445
+
1446
+ .search-icon {
1447
+ position: absolute;
1448
+ left: 0.875rem;
1449
+ top: 50%;
1450
+ transform: translateY(-50%);
1451
+ width: 16px;
1452
+ height: 16px;
1453
+ color: var(--color-text-muted);
1454
+ pointer-events: none;
1455
+ }
1456
+
1457
+ .search-input {
1458
+ width: 100%;
1459
+ padding: 0.625rem 1rem 0.625rem 2.5rem;
1460
+ border: 2px solid var(--color-border);
1461
+ border-radius: var(--radius-md);
1462
+ background: var(--color-surface);
1463
+ color: var(--color-text);
1464
+ font-size: 0.875rem;
1465
+ transition: all var(--transition-base);
1466
+ }
1467
+
1468
+ .search-input:focus {
1469
+ outline: none;
1470
+ border-color: var(--color-primary);
1471
+ box-shadow: 0 0 0 3px var(--color-tag-bg);
1472
+ }
1473
+
1474
+ .search-input::placeholder {
1475
+ color: var(--color-text-muted);
1476
+ }
1477
+
1478
+ .tags-filter-block {
1479
+ display: flex;
1480
+ flex-direction: column;
1481
+ align-items: flex-start;
1482
+ gap: 0.6rem;
1483
+ }
1484
+
1485
+ .tags-filter {
1486
+ display: flex;
1487
+ flex-wrap: wrap;
1488
+ gap: 0.5rem;
1489
+ width: 100%;
1490
+ max-height: var(--expanded-height, none);
1491
+ overflow: hidden;
1492
+ transition: max-height var(--transition-base);
1493
+ }
1494
+
1495
+ .tags-filter.is-collapsed {
1496
+ max-height: var(--collapsed-height);
1497
+ }
1498
+
1499
+ .tags-filter .tag-btn:focus-visible {
1500
+ outline-offset: -3px;
1501
+ }
1502
+
1503
+ .tags-filter-toggle {
1504
+ display: inline-flex;
1505
+ align-items: center;
1506
+ padding: 0;
1507
+ border: none;
1508
+ background: transparent;
1509
+ color: var(--color-text-muted);
1510
+ font-size: 0.8rem;
1511
+ font-weight: 600;
1512
+ cursor: pointer;
1513
+ transition: color var(--transition-fast);
1514
+ }
1515
+
1516
+ .tags-filter-toggle:hover {
1517
+ color: var(--color-secondary);
1518
+ }
1519
+
1520
+ .tags-filter-toggle[hidden] {
1521
+ display: none;
1522
+ }
1523
+
1524
+ .tag-btn {
1525
+ padding: 0.375rem 0.875rem;
1526
+ border: 1px solid var(--color-border);
1527
+ border-radius: var(--radius-full);
1528
+ background: var(--color-surface);
1529
+ color: var(--color-text-muted);
1530
+ font-size: 0.8rem;
1531
+ font-weight: 500;
1532
+ cursor: pointer;
1533
+ transition: all var(--transition-fast);
1534
+ }
1535
+
1536
+ .tag-btn:hover {
1537
+ border-color: var(--color-secondary);
1538
+ color: var(--color-text);
1539
+ }
1540
+
1541
+ .tag-btn.active {
1542
+ background: var(--color-secondary);
1543
+ color: var(--color-bg);
1544
+ border-color: var(--color-secondary);
1545
+ }
1546
+
1547
+ .tag-btn.hidden-by-filter,
1548
+ .category-btn.hidden-by-filter {
1549
+ display: none;
1550
+ }
1551
+
1552
+ .blog-controls {
1553
+ position: relative;
1554
+ }
1555
+
1556
+ .posts-list {
1557
+ display: flex;
1558
+ flex-direction: column;
1559
+ gap: 1rem;
1560
+ }
1561
+
1562
+ .no-results {
1563
+ text-align: center;
1564
+ color: var(--color-text-muted);
1565
+ padding: 3rem;
1566
+ font-size: 1rem;
1567
+ }
1568
+
1569
+ .load-more-wrap {
1570
+ display: flex;
1571
+ justify-content: center;
1572
+ margin-top: 1.5rem;
1573
+ min-height: 2.75rem;
1574
+ }
1575
+
1576
+ .load-more-wrap.hidden {
1577
+ visibility: hidden;
1578
+ pointer-events: none;
1579
+ }
1580
+
1581
+ .load-more-btn {
1582
+ padding: 0.65rem 1.2rem;
1583
+ border-radius: var(--radius-md);
1584
+ border: 1px solid var(--color-border);
1585
+ background: var(--color-surface);
1586
+ color: var(--color-text);
1587
+ cursor: pointer;
1588
+ transition: all var(--transition-fast);
1589
+ font-size: 0.88rem;
1590
+ }
1591
+
1592
+ .load-more-btn:hover {
1593
+ border-color: var(--color-secondary);
1594
+ color: var(--color-secondary);
1595
+ transform: translateY(-1px);
1596
+ }
1597
+
1598
+ /* ===== FOOTER ===== */
1599
+ .footer {
1600
+ background: var(--color-surface);
1601
+ border-top: 1px solid var(--color-border);
1602
+ padding: 2rem;
1603
+ }
1604
+
1605
+ .footer-content {
1606
+ max-width: var(--max-width);
1607
+ margin: 0 auto;
1608
+ text-align: center;
1609
+ }
1610
+
1611
+ .copyright {
1612
+ font-size: 0.875rem;
1613
+ color: var(--color-text-muted);
1614
+ margin-bottom: 0.5rem;
1615
+ }
1616
+
1617
+ .site-links {
1618
+ font-size: 0.82rem;
1619
+ color: var(--color-text-muted);
1620
+ display: inline-flex;
1621
+ align-items: center;
1622
+ gap: 0.45rem;
1623
+ margin-bottom: 0.5rem;
1624
+ }
1625
+
1626
+ .site-links a {
1627
+ color: var(--color-text-muted);
1628
+ text-decoration: none;
1629
+ transition: color var(--transition-fast);
1630
+ }
1631
+
1632
+ .site-links a:hover {
1633
+ color: var(--color-secondary);
1634
+ }
1635
+
1636
+ .icp {
1637
+ font-size: 0.8rem;
1638
+ color: var(--color-text-muted);
1639
+ }
1640
+
1641
+ .icp a {
1642
+ color: var(--color-text-muted);
1643
+ transition: color var(--transition-fast);
1644
+ }
1645
+
1646
+ .icp a:hover {
1647
+ color: var(--color-primary);
1648
+ }
1649
+
1650
+ /* ===== RESPONSIVE ===== */
1651
+ @media (max-width: 900px) {
1652
+ .hero-content {
1653
+ width: min(94vw, 720px);
1654
+ border-radius: 24px;
1655
+ }
1656
+
1657
+ .hero-shell {
1658
+ grid-template-columns: 1fr;
1659
+ }
1660
+
1661
+ .hero-copy {
1662
+ text-align: center;
1663
+ padding: 0.25rem 0;
1664
+ display: flex;
1665
+ flex-direction: column;
1666
+ align-items: center;
1667
+ }
1668
+
1669
+ .hero-name,
1670
+ .hero-tagline {
1671
+ max-width: none;
1672
+ }
1673
+
1674
+ .hero-name {
1675
+ margin-left: auto;
1676
+ margin-right: auto;
1677
+ }
1678
+
1679
+ .hero-meta,
1680
+ .hero-highlights,
1681
+ .hero-actions {
1682
+ justify-content: center;
1683
+ }
1684
+
1685
+ .hero-profile-card {
1686
+ justify-content: center;
1687
+ text-align: left;
1688
+ }
1689
+ }
1690
+
1691
+ @media (max-width: 600px) {
1692
+ .hero {
1693
+ align-items: center;
1694
+ padding-top: 0;
1695
+ }
1696
+
1697
+ .hero-content {
1698
+ border-radius: 20px;
1699
+ padding: 0.9rem;
1700
+ }
1701
+
1702
+ .hero-actions {
1703
+ display: flex;
1704
+ justify-content: center;
1705
+ align-items: center;
1706
+ flex-wrap: nowrap;
1707
+ gap: 0.6rem;
1708
+ }
1709
+
1710
+ .hero-btn {
1711
+ position: relative;
1712
+ flex: 0 0 3.1rem;
1713
+ width: 3.1rem;
1714
+ min-width: 3.1rem;
1715
+ height: 3.1rem;
1716
+ min-height: 3.1rem;
1717
+ padding: 0;
1718
+ border-radius: 999px;
1719
+ text-align: center;
1720
+ font-size: 0;
1721
+ gap: 0;
1722
+ overflow: hidden;
1723
+ }
1724
+
1725
+ .hero-kicker {
1726
+ display: inline-flex;
1727
+ margin-bottom: 0.7rem;
1728
+ font-size: 0.66rem;
1729
+ }
1730
+
1731
+ .hero-avatar-mobile {
1732
+ display: flex;
1733
+ width: 84px;
1734
+ height: 84px;
1735
+ margin: 0 auto 0.7rem;
1736
+ border-radius: 50%;
1737
+ overflow: hidden;
1738
+ border: 4px solid var(--color-primary);
1739
+ box-shadow: 0 8px 32px rgba(255, 216, 3, 0.25);
1740
+ animation: avatarPulse 3s ease-in-out infinite;
1741
+ }
1742
+
1743
+ .hero-name {
1744
+ font-size: clamp(2.2rem, 13vw, 3rem);
1745
+ max-width: none;
1746
+ margin-bottom: 0.55rem;
1747
+ }
1748
+
1749
+ .hero-tagline {
1750
+ font-size: 0.94rem;
1751
+ line-height: 1.55;
1752
+ margin-bottom: 0.8rem;
1753
+ }
1754
+
1755
+ .hero-meta,
1756
+ .hero-highlights,
1757
+ .hero-location,
1758
+ .hero-update {
1759
+ display: none;
1760
+ }
1761
+
1762
+ .hero-panel {
1763
+ gap: 0.65rem;
1764
+ }
1765
+
1766
+ .hero-profile-card {
1767
+ display: none;
1768
+ }
1769
+
1770
+ .hero-signature {
1771
+ display: none;
1772
+ }
1773
+
1774
+ .hero-metrics {
1775
+ grid-template-columns: repeat(3, minmax(0, 1fr));
1776
+ gap: 0.5rem;
1777
+ }
1778
+
1779
+ .metric-card {
1780
+ padding: 0.72rem 0.45rem;
1781
+ border-radius: 14px;
1782
+ }
1783
+
1784
+ .metric-value {
1785
+ font-size: 1.35rem;
1786
+ margin-bottom: 0.28rem;
1787
+ }
1788
+
1789
+ .metric-label {
1790
+ font-size: 0.66rem;
1791
+ line-height: 1.35;
1792
+ }
1793
+
1794
+ .scroll-indicator {
1795
+ margin-top: 0.9rem;
1796
+ gap: 0.4rem;
1797
+ transform: scale(0.88);
1798
+ }
1799
+
1800
+ .hero-btn-icon {
1801
+ position: absolute;
1802
+ inset: 50% auto auto 50%;
1803
+ transform: translate(-50%, -50%);
1804
+ width: 1.1rem;
1805
+ height: 1.1rem;
1806
+ }
1807
+
1808
+ .hero-btn-label {
1809
+ position: absolute;
1810
+ width: 1px;
1811
+ height: 1px;
1812
+ padding: 0;
1813
+ margin: -1px;
1814
+ overflow: hidden;
1815
+ clip: rect(0, 0, 0, 0);
1816
+ white-space: nowrap;
1817
+ border: 0;
1818
+ }
1819
+
1820
+ .blog-title-row {
1821
+ flex-direction: column;
1822
+ align-items: flex-start;
1823
+ gap: 0.5rem;
1824
+ }
1825
+
1826
+ .search-float-btn {
1827
+ right: 1rem;
1828
+ top: 1rem;
1829
+ }
1830
+
1831
+ .search-modal {
1832
+ justify-content: center;
1833
+ padding: 5rem 1rem 1rem;
1834
+ }
1835
+
1836
+ .search-modal-panel {
1837
+ width: min(680px, 100%);
1838
+ }
1839
+
1840
+ .search-wrapper {
1841
+ max-width: 100%;
1842
+ }
1843
+
1844
+ .controls-right {
1845
+ align-items: stretch;
1846
+ width: 100%;
1847
+ }
1848
+
1849
+ }
1850
+
1851
+ @media (max-width: 899px) {
1852
+ .hot-content-carousel-wrapper {
1853
+ position: relative;
1854
+ -webkit-user-select: none;
1855
+ user-select: none;
1856
+ -webkit-touch-callout: none;
1857
+ }
1858
+
1859
+ .hot-content-carousel {
1860
+ overflow-x: auto;
1861
+ scroll-snap-type: x mandatory;
1862
+ -webkit-overflow-scrolling: touch;
1863
+ scrollbar-width: none;
1864
+ padding: 0 0.25rem 0.25rem;
1865
+ }
1866
+
1867
+ .hot-content-carousel::-webkit-scrollbar {
1868
+ display: none;
1869
+ }
1870
+
1871
+ .hot-content-list {
1872
+ display: flex;
1873
+ flex-wrap: nowrap;
1874
+ gap: 0.75rem;
1875
+ width: 100%;
1876
+ pointer-events: none;
1877
+ }
1878
+
1879
+ .hot-content-list .hot-content-item {
1880
+ pointer-events: auto;
1881
+ }
1882
+
1883
+ .hot-content-item {
1884
+ flex: 0 0 100%;
1885
+ width: 100%;
1886
+ max-width: 100%;
1887
+ scroll-snap-align: start;
1888
+ }
1889
+
1890
+ .hot-image-wrap {
1891
+ aspect-ratio: 18 / 9;
1892
+ }
1893
+
1894
+ .hot-overlay-title {
1895
+ opacity: 1;
1896
+ transform: none;
1897
+ font-size: 0.86rem;
1898
+ }
1899
+
1900
+ .hot-scroll-indicator {
1901
+ position: absolute;
1902
+ right: 1rem;
1903
+ bottom: 1rem;
1904
+ display: flex;
1905
+ gap: 5px;
1906
+ z-index: 10;
1907
+ pointer-events: none;
1908
+ }
1909
+
1910
+ .hot-scroll-dot {
1911
+ width: 6px;
1912
+ height: 6px;
1913
+ border-radius: 50%;
1914
+ background: rgba(255, 255, 255, 0.5);
1915
+ transition: background 0.25s ease, transform 0.25s ease;
1916
+ }
1917
+
1918
+ .hot-scroll-dot.active {
1919
+ background: #fff;
1920
+ transform: scale(1.2);
1921
+ }
1922
+
1923
+ .hot-content-item:hover {
1924
+ transform: none;
1925
+ }
1926
+ }
1927
+
1928
+ /* Desktop: hide scroll indicator */
1929
+ @media (min-width: 900px) {
1930
+ .hot-scroll-indicator {
1931
+ display: none;
1932
+ }
1933
+
1934
+ .hot-content-carousel-wrapper {
1935
+ display: contents;
1936
+ }
1937
+ }
1938
+
1939
+ @media (prefers-reduced-motion: reduce) {
1940
+ .hero * {
1941
+ animation: none !important;
1942
+ }
1943
+
1944
+ .hero-blob,
1945
+ .hero-content,
1946
+ .hero-gradient,
1947
+ .hero-pattern {
1948
+ animation: none !important;
1949
+ transform: none !important;
1950
+ transition: none !important;
1951
+ }
1952
+ }
1953
+
1954
+ /* Small static shapes keep the welcome area playful without a rendering loop. */
1955
+
1956
+ .hero-blob { position: absolute; pointer-events: none; }
1957
+
1958
+ .blob-1 { width: 220px; height: 220px; border: 38px solid var(--color-accent-soft); border-radius: 50%; left: -90px; top: 12%; }
1959
+
1960
+ .blob-2 { width: 160px; height: 160px; right: 3%; top: 12%; background: var(--color-play); opacity: .7; transform: rotate(15deg); clip-path: polygon(50% 0%,61% 28%,85% 15%,72% 39%,100% 50%,72% 61%,85% 85%,61% 72%,50% 100%,39% 72%,15% 85%,28% 61%,0% 50%,28% 39%,15% 15%,39% 28%); }
1961
+
1962
+ .blob-3 { width: 230px; height: 110px; border: 2px solid var(--color-primary); border-radius: 50%; left: 15%; bottom: 6%; transform: rotate(-20deg); opacity: .2; }
1963
+
1964
+ .hero-masthead { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding-bottom: 1.25rem; margin-bottom: 2.5rem; border-bottom: 1px solid var(--color-border); color: var(--color-text-muted); font: .68rem var(--font-mono); letter-spacing: .12em; }
1965
+
1966
+ .hero-wordmark { display: inline-flex; align-items: center; gap: .3rem; color: var(--color-text); font: 700 1.2rem var(--font-family); letter-spacing: -.04em; }
1967
+
1968
+ .wordmark-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-accent); }
1969
+
1970
+ .hero-name::after { content: ''; position: absolute; left: 0; right: -4%; bottom: 2%; height: 22%; border-radius: 50% 20% 40% 10%; background: var(--color-play); opacity: .5; transform: rotate(-3deg); z-index: -1; }
1971
+
1972
+ .hero-chip:nth-child(2) { background: var(--color-accent-soft); transform: rotate(-3deg); }
1973
+
1974
+ .hero-chip:nth-child(3) { background: var(--color-tag-bg); transform: rotate(2deg); }
1975
+
1976
+ .profile-sticker { position: absolute; right: -10px; top: -14px; padding: .35rem .9rem; background: var(--color-primary); color: var(--color-on-primary); border: 1px solid var(--color-text); border-radius: 8px; font-size: .8rem; transform: rotate(6deg); }
1977
+
1978
+ .profile-note { font-weight: 650; font-size: 1.05rem; }
1979
+
1980
+ .hero-metrics { margin-top: .6rem; }
1981
+
1982
+ .metric-card:nth-child(2) { background: var(--color-accent-soft); }
1983
+
1984
+ .metric-card:nth-child(3) { background: var(--color-tag-bg); }
1985
+
1986
+ .section-eyebrow { color: var(--color-text-muted); font: .66rem var(--font-mono); letter-spacing: .14em; margin-bottom: .4rem; }
1987
+
1988
+ .title-dot { color: var(--color-primary); }
1989
+
1990
+ .section-spark { display: inline-block; color: var(--color-primary); font-size: 1.25rem; vertical-align: middle; margin-right: .3rem; }
1991
+
1992
+ @media (max-width: 900px) {
1993
+ .hero-masthead { margin-bottom: 1.3rem; }
1994
+ .hero-profile-card { transform: none; flex-direction: row; flex-wrap: wrap; min-height: auto; padding: 1rem; }
1995
+ .profile-note { display: none; }
1996
+ .hero-avatar-wrapper { width: 64px; height: 64px; }
1997
+ }
1998
+
1999
+ @media (max-width: 600px) {
2000
+ .hero-content { padding: 1rem 1.25rem; width: min(96vw, 480px); }
2001
+ .hero-masthead { padding-bottom: .8rem; margin-bottom: 1.2rem; font-size: .54rem; }
2002
+ .hero-name { font-size: 3.5rem; }
2003
+ .hero-avatar-mobile { animation: none; border-color: var(--color-surface); box-shadow: 5px 5px 0 var(--color-accent), -5px -5px 0 var(--color-play); transform: rotate(-7deg); margin-bottom: 1rem; }
2004
+ .hero-actions { gap: .65rem; flex-wrap: wrap; }
2005
+ .hero-btn.primary { flex: 0 0 auto; width: auto; padding: 0 1rem; gap: .5rem; font-size: .85rem; }
2006
+ .hero-btn.primary .hero-btn-icon { position: static; transform: none; }
2007
+ .hero-btn.primary .hero-btn-label { position: static; width: auto; height: auto; clip: auto; margin: 0; }
2008
+ .hero-metrics { margin-top: .1rem; }
2009
+ .blob-2 { width: 95px; height: 95px; top: 5%; right: -20px; }
2010
+ .blob-3 { bottom: 2%; }
2011
+ .blog-title-row { flex-direction: row; align-items: flex-end; gap: .6rem; }
2012
+ .blog-title { font-size: 1.45rem; }
2013
+ .hot-content-section { padding: .8rem; }
2014
+ }
2015
+
2016
+ @media (max-height: 650px) and (min-width: 601px) {
2017
+ .hero-masthead { margin-bottom: .8rem; padding-bottom: .5rem; }
2018
+ .hero-shell { grid-template-columns: minmax(0, 1.35fr) minmax(0, .9fr); gap: 1.25rem; }
2019
+ .hero-copy { text-align: left; align-items: flex-start; }
2020
+ .hero-meta, .hero-highlights { display: none; }
2021
+ .hero-profile-card { min-height: auto; padding: 1rem; }
2022
+ .hero-avatar-wrapper { width: 64px; height: 64px; }
2023
+ .hero-name { font-size: 3.5rem; margin-left: 0; }
2024
+ .hero-tagline { font-size: .9rem; line-height: 1.5; }
2025
+ .hero-btn { padding: .65rem .85rem; }
2026
+ .metric-card { padding: .6rem; }
2027
+ .metric-value { font-size: 1.5rem; }
2028
+ .metric-label { font-size: .65rem; }
2029
+ .scroll-indicator { margin-top: .5rem; }
2030
+ .scroll-mouse { display: none; }
2031
+ }
2032
+
2033
+ @media (max-width: 600px) and (max-height: 700px) {
2034
+ .hero-content { padding: .6rem 1rem; }
2035
+ .hero-masthead { margin-bottom: .65rem; padding-bottom: .45rem; }
2036
+ .hero-shell { gap: .65rem; }
2037
+ .hero-kicker { font-size: .58rem; padding: .3rem .5rem; margin-bottom: .65rem; }
2038
+ .hero-avatar-mobile { width: 64px; height: 64px; margin-bottom: .6rem; }
2039
+ .hero-name { font-size: 2.8rem; margin-bottom: .45rem; }
2040
+ .hero-tagline { font-size: .84rem; line-height: 1.5; margin-bottom: .65rem; }
2041
+ .metric-card { padding: .6rem .4rem; }
2042
+ .scroll-indicator { margin-top: .4rem; gap: .25rem; }
2043
+ .scroll-mouse { width: 20px; height: 30px; }
2044
+ }
2045
+ </style>
2046
+
2047
+ <script>
2048
+ import '../scripts/home';
2049
+ </script>