@anglefeint/astro-theme 0.1.2 → 0.1.4

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.
@@ -0,0 +1,575 @@
1
+ /* Cyber theme styles extracted from global.css */
2
+ /* ========== Blade Runner 博客列表页 (body.cyber-page) ========== */
3
+ body.cyber-page {
4
+ background: #090b12 !important;
5
+ background-image: none !important;
6
+ background-size: auto !important;
7
+ min-height: 100vh !important;
8
+ --chrome-bg: rgba(7, 13, 24, 0.72);
9
+ --chrome-border: rgba(112, 196, 255, 0.2);
10
+ --chrome-link: rgba(196, 226, 255, 0.92);
11
+ --chrome-link-hover: rgba(232, 206, 245, 0.98);
12
+ --chrome-active: rgba(228, 158, 224, 0.9);
13
+ --chrome-text-muted: rgba(156, 188, 224, 0.76);
14
+ }
15
+ body.cyber-page::before {
16
+ content: "";
17
+ position: fixed;
18
+ inset: 0;
19
+ z-index: -1;
20
+ background: linear-gradient(
21
+ 180deg,
22
+ #05070b 0%,
23
+ #090c14 20%,
24
+ #111a2d 52%,
25
+ #090c14 80%,
26
+ #05070b 100%
27
+ );
28
+ }
29
+ body.cyber-page::after {
30
+ content: "";
31
+ position: fixed;
32
+ inset: 0;
33
+ z-index: -1;
34
+ background:
35
+ radial-gradient(
36
+ ellipse 82% 52% at 50% 18%,
37
+ rgba(110, 186, 255, 0.14) 0%,
38
+ transparent 50%
39
+ ),
40
+ radial-gradient(
41
+ ellipse 62% 42% at 82% 78%,
42
+ rgba(255, 132, 88, 0.06) 0%,
43
+ transparent 40%
44
+ ),
45
+ radial-gradient(
46
+ ellipse 52% 37% at 20% 62%,
47
+ rgba(226, 150, 214, 0.06) 0%,
48
+ transparent 45%
49
+ );
50
+ animation: cyber-fog-drift 20s ease-in-out infinite alternate;
51
+ pointer-events: none;
52
+ }
53
+ @keyframes cyber-fog-drift {
54
+ 0% {
55
+ opacity: 0.7;
56
+ transform: translate(-2%, -1%);
57
+ }
58
+ 100% {
59
+ opacity: 1;
60
+ transform: translate(2%, 1%);
61
+ }
62
+ }
63
+ body.cyber-page .cyber-rain {
64
+ position: fixed;
65
+ inset: 0;
66
+ pointer-events: none;
67
+ z-index: 6;
68
+ overflow: hidden;
69
+ contain: layout paint;
70
+ }
71
+ /* Blade Runner: 雨滴 - 白色中脏脏的感觉,非琥珀也非冷青 */
72
+ body.cyber-page .cyber-rain-drop {
73
+ position: absolute;
74
+ top: -20px;
75
+ width: 6px;
76
+ height: 38px;
77
+ clip-path: polygon(1.5px 0, 4.5px 0, 6px 100%, 0 100%);
78
+ will-change: transform;
79
+ background: linear-gradient(
80
+ to bottom,
81
+ transparent 0%,
82
+ rgba(210, 208, 198, 0.38) 40%,
83
+ rgba(195, 190, 182, 0.52) 70%,
84
+ transparent 100%
85
+ );
86
+ animation: cyber-rain-fall linear infinite;
87
+ }
88
+ @keyframes cyber-rain-fall {
89
+ to {
90
+ transform: translateY(100vh);
91
+ }
92
+ }
93
+ /* AI page: scanlines only on header and footer; fade on hover */
94
+ body.cyber-page .cyber-spotlight {
95
+ position: fixed;
96
+ top: 0;
97
+ left: 0;
98
+ width: calc(hypot(100vw, 100vh) * 1.3 / 1.41421356);
99
+ height: calc(hypot(100vw, 100vh) * 1.3 / 1.41421356);
100
+ pointer-events: none;
101
+ z-index: 5;
102
+ contain: layout paint;
103
+ }
104
+ body.cyber-page .cyber-spotlight-tl {
105
+ position: absolute;
106
+ inset: 0;
107
+ transform-origin: 0 0;
108
+ background: conic-gradient(
109
+ from 180deg at 0 0,
110
+ transparent 0deg 302deg,
111
+ rgba(120, 192, 255, 0.18) 304deg,
112
+ rgba(96, 182, 255, 0.32) 307deg,
113
+ rgba(206, 234, 255, 0.92) 310deg,
114
+ rgba(96, 182, 255, 0.32) 313deg,
115
+ rgba(120, 192, 255, 0.18) 316deg,
116
+ transparent 319deg 360deg
117
+ );
118
+ animation: cyber-spotlight-sweep-tl 12s ease-in-out infinite;
119
+ }
120
+ body.cyber-page .cyber-spotlight-tr {
121
+ position: absolute;
122
+ inset: 0;
123
+ transform-origin: 100% 0;
124
+ background: conic-gradient(
125
+ from 180deg at 100% 0,
126
+ transparent 0deg 33deg,
127
+ rgba(120, 192, 255, 0.18) 35deg,
128
+ rgba(96, 182, 255, 0.32) 38deg,
129
+ rgba(206, 234, 255, 0.92) 41deg,
130
+ rgba(96, 182, 255, 0.32) 44deg,
131
+ rgba(120, 192, 255, 0.18) 47deg,
132
+ transparent 50deg 360deg
133
+ );
134
+ animation: cyber-spotlight-sweep-tr 24s ease-in-out infinite;
135
+ animation-delay: -1.5s;
136
+ }
137
+ @keyframes cyber-spotlight-sweep-tl {
138
+ 0% {
139
+ transform: rotate(50deg);
140
+ }
141
+ 50% {
142
+ transform: rotate(-50deg);
143
+ }
144
+ 100% {
145
+ transform: rotate(50deg);
146
+ }
147
+ }
148
+ @keyframes cyber-spotlight-sweep-tr {
149
+ 0%,
150
+ 100% {
151
+ transform: rotate(-60deg);
152
+ }
153
+ 50% {
154
+ transform: rotate(60deg);
155
+ }
156
+ }
157
+ body.cyber-page .cyber-flicker {
158
+ position: fixed;
159
+ inset: 0;
160
+ contain: layout paint;
161
+ background:
162
+ radial-gradient(
163
+ ellipse 25% 30% at 85% 20%,
164
+ rgba(255, 146, 96, 0.18) 0%,
165
+ transparent 55%
166
+ ),
167
+ radial-gradient(
168
+ ellipse 20% 24% at 20% 68%,
169
+ rgba(96, 182, 255, 0.28) 0%,
170
+ transparent 55%
171
+ ),
172
+ radial-gradient(
173
+ ellipse 28% 35% at 70% 85%,
174
+ rgba(224, 146, 212, 0.2) 0%,
175
+ transparent 55%
176
+ );
177
+ animation: cyber-neon-flicker-glow 6s ease-in-out infinite;
178
+ pointer-events: none;
179
+ z-index: 0;
180
+ }
181
+ @keyframes cyber-neon-flicker-glow {
182
+ 0%,
183
+ 100% {
184
+ opacity: 0.8;
185
+ }
186
+ 25% {
187
+ opacity: 1;
188
+ }
189
+ 50% {
190
+ opacity: 0.5;
191
+ }
192
+ 75% {
193
+ opacity: 0.95;
194
+ }
195
+ }
196
+ body.cyber-page .cyber-haze {
197
+ position: fixed;
198
+ inset: 0;
199
+ contain: layout paint;
200
+ background:
201
+ radial-gradient(
202
+ ellipse 100% 80% at 50% 50%,
203
+ rgba(52, 84, 128, 0.08) 0%,
204
+ transparent 60%
205
+ ),
206
+ radial-gradient(
207
+ ellipse 40% 30% at 30% 30%,
208
+ rgba(224, 144, 208, 0.05) 0%,
209
+ transparent 50%
210
+ ),
211
+ radial-gradient(
212
+ ellipse 35% 25% at 70% 70%,
213
+ rgba(255, 134, 92, 0.04) 0%,
214
+ transparent 50%
215
+ );
216
+ animation: cyber-haze-drift 20s ease-in-out infinite alternate;
217
+ pointer-events: none;
218
+ z-index: 1;
219
+ }
220
+ @keyframes cyber-haze-drift {
221
+ 0% {
222
+ opacity: 0.5;
223
+ transform: translate(3%, 2%) scale(1.05);
224
+ }
225
+ 100% {
226
+ opacity: 1;
227
+ transform: translate(-3%, -2%) scale(0.95);
228
+ }
229
+ }
230
+ body.cyber-page .cyber-vignette {
231
+ position: fixed;
232
+ inset: 0;
233
+ contain: layout paint;
234
+ background: radial-gradient(
235
+ ellipse 80% 80% at 50% 50%,
236
+ transparent 40%,
237
+ rgba(0, 0, 0, 0.4) 100%
238
+ );
239
+ pointer-events: none;
240
+ z-index: 3;
241
+ }
242
+ body.cyber-page .cyber-rain-drop--thin {
243
+ width: 4px;
244
+ height: 28px;
245
+ clip-path: polygon(0.5px 0, 3.5px 0, 4px 100%, 0 100%);
246
+ }
247
+ body.cyber-page .cyber-rain-drop--fog {
248
+ opacity: 0.15;
249
+ filter: blur(0.5px);
250
+ }
251
+ body.cyber-page .cyber-rain-drop--skew {
252
+ animation-name: cyber-rain-fall-skew;
253
+ }
254
+ @keyframes cyber-rain-fall-skew {
255
+ to {
256
+ transform: skewX(-3deg) translateY(100vh);
257
+ }
258
+ }
259
+ body.cyber-page .cyber-dust {
260
+ position: fixed;
261
+ inset: 0;
262
+ pointer-events: none;
263
+ z-index: 2;
264
+ overflow: hidden;
265
+ contain: layout paint;
266
+ }
267
+ body.cyber-page .cyber-dust-particle {
268
+ position: absolute;
269
+ border-radius: 50%;
270
+ will-change: transform;
271
+ background: rgba(176, 216, 248, 0.68);
272
+ box-shadow:
273
+ 0 0 10px rgba(126, 196, 255, 0.35),
274
+ 0 0 20px rgba(214, 146, 210, 0.16);
275
+ animation: cyber-dust-float linear infinite;
276
+ }
277
+ @keyframes cyber-dust-float {
278
+ 0% {
279
+ transform: translate(0, 0) scale(1);
280
+ opacity: 0.7;
281
+ }
282
+ 25% {
283
+ transform: translate(15px, -8px) scale(1.1);
284
+ opacity: 0.95;
285
+ }
286
+ 50% {
287
+ transform: translate(-10px, -20px) scale(0.9);
288
+ opacity: 0.8;
289
+ }
290
+ 75% {
291
+ transform: translate(8px, -15px) scale(1.05);
292
+ opacity: 0.9;
293
+ }
294
+ 100% {
295
+ transform: translate(0, -30px) scale(1);
296
+ opacity: 0.7;
297
+ }
298
+ }
299
+ body.cyber-page header {
300
+ position: fixed;
301
+ top: 0;
302
+ left: 0;
303
+ right: 0;
304
+ z-index: 6;
305
+ backdrop-filter: blur(3px);
306
+ -webkit-backdrop-filter: blur(3px);
307
+ }
308
+ body.cyber-page main {
309
+ position: relative;
310
+ z-index: 5;
311
+ width: 960px;
312
+ padding-top: calc(3em + 56px);
313
+ }
314
+ body.cyber-page .title,
315
+ body.cyber-page .date {
316
+ color: rgba(202, 228, 255, 0.93);
317
+ }
318
+ body.cyber-page .date {
319
+ color: rgba(150, 186, 228, 0.68);
320
+ }
321
+ body.cyber-page ul {
322
+ display: flex;
323
+ flex-wrap: wrap;
324
+ gap: 2rem;
325
+ list-style: none;
326
+ margin: 0;
327
+ padding: 0;
328
+ }
329
+ body.cyber-page ul li {
330
+ width: calc(50% - 1rem);
331
+ }
332
+ body.cyber-page ul li * {
333
+ text-decoration: none;
334
+ }
335
+ body.cyber-page ul li:first-child {
336
+ width: 100%;
337
+ margin-bottom: 1rem;
338
+ text-align: center;
339
+ }
340
+ body.cyber-page ul li:first-child img {
341
+ width: 100%;
342
+ }
343
+ body.cyber-page ul li:first-child .title {
344
+ font-size: 2.369rem;
345
+ }
346
+ body.cyber-page ul li a {
347
+ display: block;
348
+ position: relative;
349
+ padding: 1rem;
350
+ border-radius: 4px;
351
+ border: 1px solid rgba(116, 194, 255, 0.24);
352
+ box-shadow:
353
+ 0 0 6px rgba(100, 182, 255, 0.1),
354
+ 0 0 16px rgba(88, 164, 240, 0.07),
355
+ inset 0 0 8px rgba(224, 146, 210, 0.03);
356
+ transition:
357
+ border-color 0.2s,
358
+ box-shadow 0.3s;
359
+ }
360
+ body.cyber-page ul li a:hover {
361
+ border-color: rgba(124, 204, 255, 0.62);
362
+ box-shadow:
363
+ 0 0 10px rgba(112, 196, 255, 0.3),
364
+ 0 0 24px rgba(214, 146, 210, 0.2),
365
+ inset 0 0 18px rgba(136, 204, 255, 0.08);
366
+ animation: cyber-neon-flicker 0.45s ease-in-out infinite;
367
+ }
368
+ @keyframes cyber-neon-flicker {
369
+ 0%,
370
+ 100% {
371
+ box-shadow:
372
+ 0 0 10px rgba(112, 196, 255, 0.3),
373
+ 0 0 24px rgba(214, 146, 210, 0.2),
374
+ inset 0 0 18px rgba(136, 204, 255, 0.08);
375
+ }
376
+ 50% {
377
+ box-shadow:
378
+ 0 0 7px rgba(112, 196, 255, 0.22),
379
+ 0 0 15px rgba(214, 146, 210, 0.14),
380
+ inset 0 0 10px rgba(136, 204, 255, 0.06);
381
+ }
382
+ }
383
+ body.cyber-page ul li a:hover .title {
384
+ animation: cyber-glitch 0.3s ease-in-out;
385
+ color: rgb(212, 236, 255);
386
+ text-shadow:
387
+ 0 0 10px rgba(120, 200, 255, 0.62),
388
+ 0 0 22px rgba(222, 150, 214, 0.3),
389
+ 0 0 34px rgba(90, 170, 240, 0.2);
390
+ }
391
+ @keyframes cyber-glitch {
392
+ 0% {
393
+ transform: translate(0);
394
+ text-shadow: 0 0 8px rgba(120, 200, 255, 0.55);
395
+ }
396
+ 20% {
397
+ transform: translate(-2px, 2px);
398
+ text-shadow:
399
+ 2px 0 rgba(224, 150, 214, 0.55),
400
+ -2px 0 rgba(120, 202, 255, 0.5);
401
+ }
402
+ 40% {
403
+ transform: translate(2px, -2px);
404
+ text-shadow:
405
+ -2px 0 rgba(120, 202, 255, 0.5),
406
+ 2px 0 rgba(224, 150, 214, 0.55);
407
+ }
408
+ 60% {
409
+ transform: translate(-1px, 1px);
410
+ }
411
+ 80% {
412
+ transform: translate(1px, -1px);
413
+ }
414
+ 100% {
415
+ transform: translate(0);
416
+ text-shadow: 0 0 8px rgba(120, 200, 255, 0.55);
417
+ }
418
+ }
419
+ body.cyber-page ul li a:hover .date {
420
+ color: rgba(196, 226, 255, 0.95);
421
+ text-shadow:
422
+ 0 0 10px rgba(120, 194, 255, 0.45),
423
+ 0 0 20px rgba(218, 148, 210, 0.26);
424
+ }
425
+ body.cyber-page .img-wrapper {
426
+ position: relative;
427
+ margin-bottom: 0.5rem;
428
+ border-radius: 4px;
429
+ overflow: hidden;
430
+ }
431
+ /* 水平扫线 - 日式樱花+赛博蓝 */
432
+ body.cyber-page .img-wrapper::before {
433
+ content: "";
434
+ position: absolute;
435
+ left: 0;
436
+ right: 0;
437
+ top: -20px;
438
+ height: 10px;
439
+ z-index: 3;
440
+ background: linear-gradient(
441
+ 90deg,
442
+ transparent,
443
+ rgba(255, 182, 228, 0.74),
444
+ rgba(234, 148, 214, 0.88),
445
+ rgba(170, 200, 255, 0.9),
446
+ rgba(234, 148, 214, 0.88),
447
+ rgba(255, 182, 228, 0.74),
448
+ transparent
449
+ );
450
+ box-shadow:
451
+ 0 0 24px rgba(232, 150, 214, 0.62),
452
+ 0 0 48px rgba(110, 182, 255, 0.32);
453
+ pointer-events: none;
454
+ transition: top 1.2s linear;
455
+ }
456
+ body.cyber-page ul li a:hover .img-wrapper::before {
457
+ top: 100%;
458
+ }
459
+ body.cyber-page .img-wrapper::after {
460
+ content: "";
461
+ position: absolute;
462
+ inset: 0;
463
+ z-index: 2;
464
+ box-shadow:
465
+ inset 0 0 25px rgba(108, 190, 255, 0.16),
466
+ inset 0 0 50px rgba(224, 148, 212, 0.1);
467
+ pointer-events: none;
468
+ opacity: 0;
469
+ transition: opacity 0.4s ease;
470
+ }
471
+ body.cyber-page ul li a:hover .img-wrapper::after {
472
+ opacity: 1;
473
+ }
474
+ body.cyber-page ul li img {
475
+ display: block;
476
+ width: 100%;
477
+ height: auto;
478
+ filter: saturate(0.75) contrast(1.05) brightness(0.88) sepia(0.15)
479
+ hue-rotate(-2deg);
480
+ transition:
481
+ filter 0.3s,
482
+ box-shadow 0.3s;
483
+ }
484
+ body.cyber-page ul li a:hover img {
485
+ filter: saturate(0.88) contrast(1.11) brightness(0.94) sepia(0.08)
486
+ hue-rotate(-6deg);
487
+ box-shadow:
488
+ 0 0 15px rgba(116, 194, 255, 0.22),
489
+ 0 0 30px rgba(224, 148, 212, 0.2);
490
+ }
491
+ body.cyber-page .title {
492
+ margin: 0;
493
+ line-height: 1;
494
+ transition:
495
+ color 0.2s,
496
+ text-shadow 0.2s;
497
+ }
498
+ body.cyber-page .date {
499
+ margin: 0;
500
+ transition:
501
+ color 0.2s,
502
+ text-shadow 0.2s;
503
+ }
504
+ /* BR2049: Las Vegas/baseline 橙色光晕点缀 */
505
+ body.cyber-page footer {
506
+ box-shadow:
507
+ 0 -4px 42px rgba(104, 182, 255, 0.14),
508
+ 0 -4px 36px rgba(224, 146, 210, 0.16);
509
+ }
510
+ /* BR2049: 页面加载时轻微 glitch,可察觉但不抢眼 */
511
+ body.cyber-page .cyber-load-glitch {
512
+ position: fixed;
513
+ inset: 0;
514
+ z-index: 9999;
515
+ pointer-events: none;
516
+ background: linear-gradient(
517
+ 90deg,
518
+ rgba(226, 146, 210, 0.1) 0%,
519
+ transparent 45%,
520
+ transparent 55%,
521
+ rgba(104, 182, 255, 0.12) 100%
522
+ );
523
+ mix-blend-mode: screen;
524
+ opacity: 0;
525
+ animation: cyber-load-glitch 12s ease-out 0.5s infinite;
526
+ }
527
+ @keyframes cyber-load-glitch {
528
+ /* 每 8 秒一周期:前 6.5s 静默,后 1.5s 执行 glitch */
529
+ 0%,
530
+ 81%,
531
+ 100% {
532
+ opacity: 0;
533
+ transform: translateX(0);
534
+ }
535
+ 83% {
536
+ opacity: 1;
537
+ transform: translateX(-3px);
538
+ }
539
+ 86% {
540
+ opacity: 0.9;
541
+ transform: translateX(3px);
542
+ }
543
+ 90% {
544
+ opacity: 0.5;
545
+ transform: translateX(-2px);
546
+ }
547
+ }
548
+ @media (max-width: 720px) {
549
+ body.cyber-page main {
550
+ padding-top: calc(1em + 56px);
551
+ }
552
+ body.cyber-page ul {
553
+ gap: 0.5em;
554
+ }
555
+ body.cyber-page ul li {
556
+ width: 100%;
557
+ text-align: center;
558
+ }
559
+ body.cyber-page ul li:first-child {
560
+ margin-bottom: 0;
561
+ }
562
+ body.cyber-page ul li:first-child .title {
563
+ font-size: 1.563em;
564
+ }
565
+ /* 移动端减少特效,减轻 GPU 压力 */
566
+ body.cyber-page .cyber-rain-drop:nth-child(2n) {
567
+ display: none;
568
+ }
569
+ body.cyber-page .cyber-dust-particle:nth-child(2n) {
570
+ display: none;
571
+ }
572
+ body.cyber-page .cyber-flicker {
573
+ animation-duration: 8s;
574
+ }
575
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * About page content and runtime behavior configuration.
3
+ * Used by src/pages/[lang]/about.astro and public/scripts/about-effects.js.
4
+ */
5
+ export const ABOUT_CONFIG = {
6
+ metaLine: '$ profile booted | mode: builder',
7
+ sections: {
8
+ who: 'I build digital products that balance visual narrative, writing clarity, and engineering reliability.',
9
+ what: 'I focus on frontend architecture, content systems, and multilingual publishing workflows for modern web teams.',
10
+ ethos: [
11
+ 'Design for clarity first, then add style with purpose.',
12
+ 'Prefer maintainable systems over one-off visual hacks.',
13
+ 'Ship in small iterations and improve from real feedback.',
14
+ 'Keep communication direct, specific, and accountable.',
15
+ ],
16
+ now: 'Currently exploring AI-assisted content workflows and performance-aware visual systems for static-first sites.',
17
+ contactLead: 'Open to collaboration on design-heavy developer tools, documentation systems, and publication platforms.',
18
+ signature: '> Signal received.',
19
+ },
20
+ contact: {
21
+ email: 'voidtem@users.noreply.github.com',
22
+ githubUrl: 'https://github.com/voidtem',
23
+ githubLabel: 'GitHub',
24
+ },
25
+ sidebar: {
26
+ dlData: 'DL Data',
27
+ ai: 'AI',
28
+ decryptor: 'Decryptor',
29
+ help: 'Help',
30
+ allScripts: 'All Scripts',
31
+ },
32
+ scriptsPath: '/root/bash/scripts',
33
+ modals: {
34
+ dlData: {
35
+ title: 'Downloading...',
36
+ subtitle: 'Critical Data',
37
+ },
38
+ ai: {
39
+ title: 'AI',
40
+ lines: [
41
+ '~ $ model --status',
42
+ '',
43
+ 'inference: stable',
44
+ 'context: 8k tokens',
45
+ 'latency: < 200ms',
46
+ '',
47
+ '>> system online',
48
+ ],
49
+ },
50
+ decryptor: {
51
+ title: 'Password Decryptor',
52
+ header: 'Calculating Hashes',
53
+ keysLabel: 'keys tested',
54
+ currentPassphraseLabel: 'Current passphrase:',
55
+ masterKeyLabel: 'Master key',
56
+ transientKeyLabel: 'Transient key',
57
+ },
58
+ help: {
59
+ title: 'Help',
60
+ statsLabel: 'Stats & Achievements',
61
+ typedPrefix: 'You typed:',
62
+ typedSuffix: 'characters',
63
+ },
64
+ allScripts: {
65
+ title: '/root/bash/scripts',
66
+ },
67
+ },
68
+ effects: {
69
+ backgroundLines: [
70
+ '~ $ ls -la',
71
+ 'total 42',
72
+ 'drwxr-xr-x 12 void staff 384 Jan 12 about blog projects',
73
+ 'drwxr-xr-x 8 void staff 256 Jan 11 .config .ssh keys',
74
+ '-rw-r--r-- 1 void staff 2048 Jan 10 README.md .env.gpg',
75
+ '-rwxr-xr-x 1 void staff 512 Jan 9 deploy.sh hack',
76
+ '~ $ cat .motd',
77
+ '>> welcome to the void | access granted',
78
+ ],
79
+ scrollToasts: {
80
+ p30: 'context parsed',
81
+ p60: 'inference stable',
82
+ p90: 'output finalized',
83
+ },
84
+ },
85
+ } as const;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Central config. Re-export all config modules for convenience.
3
+ */
4
+ export * from './site';
5
+ export * from './social';
6
+ export * from './theme';
7
+ export * from './about';
@@ -0,0 +1,23 @@
1
+ import type { Locale } from '../i18n/config';
2
+
3
+ /**
4
+ * Site identity config. Override via environment variables:
5
+ * PUBLIC_SITE_URL, PUBLIC_SITE_TITLE, PUBLIC_SITE_AUTHOR, PUBLIC_SITE_DESCRIPTION, PUBLIC_SITE_TAGLINE
6
+ */
7
+ const env = import.meta.env;
8
+
9
+ export const SITE_TITLE = (env.PUBLIC_SITE_TITLE as string | undefined) ?? 'My Blog';
10
+ export const SITE_DESCRIPTION =
11
+ (env.PUBLIC_SITE_DESCRIPTION as string | undefined) ??
12
+ 'Cinematic web interfaces, AI-era engineering notes, and system architecture essays.';
13
+ export const SITE_URL = (env.PUBLIC_SITE_URL as string | undefined) ?? (env.SITE as string | undefined) ?? 'https://example.com';
14
+ export const SITE_AUTHOR = (env.PUBLIC_SITE_AUTHOR as string | undefined) ?? 'Your Name';
15
+ export const SITE_TAGLINE = (env.PUBLIC_SITE_TAGLINE as string | undefined) ?? 'Built with Astro.';
16
+
17
+ export const SITE_HERO_BY_LOCALE: Record<Locale, string> = {
18
+ en: 'Write a short introduction for your site and what readers can expect from your posts.',
19
+ ja: 'このサイトの紹介文と、読者がどんな記事を期待できるかを書いてください。',
20
+ ko: '사이트 소개와 방문자가 어떤 글을 기대할 수 있는지 간단히 작성하세요.',
21
+ es: 'Escribe una breve presentación del sitio y qué tipo de contenido encontrarán tus lectores.',
22
+ zh: '在这里写一段站点简介,并告诉读者你将发布什么类型的内容。',
23
+ };
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Social links shown in Header + Footer. Set to [] to hide.
3
+ * Replace with your own links when using as a theme.
4
+ */
5
+ export interface SocialLink {
6
+ href: string;
7
+ label: string;
8
+ /** Optional: 'mastodon' | 'twitter' | 'github' for built-in icons, or omit for text-only */
9
+ icon?: 'mastodon' | 'twitter' | 'github';
10
+ }
11
+
12
+ export const SOCIAL_LINKS: SocialLink[] = [
13
+ // Replace with your links when using as a theme.
14
+ // Keep empty to hide social icons by default.
15
+ ];
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Theme behavior config.
3
+ */
4
+ export const THEME = {
5
+ /** Posts per page on blog list */
6
+ BLOG_PAGE_SIZE: 9,
7
+ /** Number of latest posts shown on home page */
8
+ HOME_LATEST_COUNT: 3,
9
+ /** Whether to enable the About page (disable to hide from nav/routes if needed) */
10
+ ENABLE_ABOUT_PAGE: true,
11
+ } as const;