@anglefeint/astro-theme 0.1.3 → 0.1.5

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
+ }
@@ -65,7 +65,7 @@ function templateFor({ slug, theme }) {
65
65
  return `---
66
66
  import type { GetStaticPaths } from 'astro';
67
67
  import ${layoutName} from '@anglefeint/astro-theme/layouts/${layoutName}.astro';
68
- import { SUPPORTED_LOCALES } from '../../i18n/config';
68
+ import { SUPPORTED_LOCALES } from '@anglefeint/astro-theme/i18n/config';
69
69
 
70
70
  export const getStaticPaths = (() => SUPPORTED_LOCALES.map((lang) => ({ params: { lang } }))) satisfies GetStaticPaths;
71
71
 
@@ -1,8 +1,8 @@
1
1
  import { mkdir, writeFile, access, readdir } from 'node:fs/promises';
2
2
  import { constants } from 'node:fs';
3
3
  import path from 'node:path';
4
+ import { SUPPORTED_LOCALES } from './i18n/locales.mjs';
4
5
 
5
- const SUPPORTED_LOCALES = ['en', 'ja', 'ko', 'es', 'zh'];
6
6
  const CONTENT_ROOT = path.resolve(process.cwd(), 'src/content/blog');
7
7
  const DEFAULT_COVERS_ROOT = path.resolve(process.cwd(), 'src/assets/blog/default-covers');
8
8
 
@@ -5,21 +5,21 @@
5
5
  export const ABOUT_CONFIG = {
6
6
  metaLine: '$ profile booted | mode: builder',
7
7
  sections: {
8
- who: 'Write a short introduction about yourself, your background, and what you care about.',
9
- what: 'Describe what you build, your core skills, and the kind of projects you want to be known for.',
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
10
  ethos: [
11
- 'Add 3-4 principles that guide how you work.',
12
- 'Use concise lines that are easy to scan.',
13
- 'Focus on practical values your readers can understand quickly.',
14
- 'Keep wording personal, clear, and honest.',
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
15
  ],
16
- now: 'Share what you are currently building or learning.',
17
- contactLead: 'Add a short collaboration note (for example: open to freelance, consulting, or full-time roles).',
18
- signature: '> replace with your own signature',
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
19
  },
20
20
  contact: {
21
- email: 'hello@example.com',
22
- githubUrl: 'https://github.com',
21
+ email: 'voidtem@users.noreply.github.com',
22
+ githubUrl: 'https://github.com/voidtem',
23
23
  githubLabel: 'GitHub',
24
24
  },
25
25
  sidebar: {
@@ -1,7 +1,11 @@
1
- export const SUPPORTED_LOCALES = ['en', 'ja', 'ko', 'es', 'zh'] as const;
2
- export type Locale = (typeof SUPPORTED_LOCALES)[number];
3
-
4
- export const DEFAULT_LOCALE: Locale = 'en';
1
+ import {
2
+ SUPPORTED_LOCALES as SUPPORTED_LOCALES_RUNTIME,
3
+ DEFAULT_LOCALE as DEFAULT_LOCALE_RUNTIME,
4
+ } from './locales.mjs';
5
+
6
+ export type Locale = 'en' | 'ja' | 'ko' | 'es' | 'zh';
7
+ export const SUPPORTED_LOCALES = SUPPORTED_LOCALES_RUNTIME as readonly Locale[];
8
+ export const DEFAULT_LOCALE: Locale = DEFAULT_LOCALE_RUNTIME as Locale;
5
9
 
6
10
  export const LOCALE_LABELS: Record<Locale, string> = {
7
11
  en: 'English',
@@ -0,0 +1,3 @@
1
+ export const SUPPORTED_LOCALES = ['en', 'ja', 'ko', 'es', 'zh'];
2
+ export const DEFAULT_LOCALE = 'en';
3
+
@@ -51,6 +51,7 @@ const {
51
51
  scanlines
52
52
  localeHrefs={localeHrefs}
53
53
  >
54
+ <link slot="head" rel="stylesheet" href="/styles/theme-ai.css" />
54
55
  <slot name="head" slot="head" />
55
56
  <slot name="body-start" slot="body-start" />
56
57
  <slot />
@@ -13,6 +13,7 @@ const { locale, title, description, localeHrefs } = Astro.props as Props;
13
13
  ---
14
14
 
15
15
  <ThemeFrame locale={locale} title={title} description={description} bodyClass="cyber-page" mainClass="page-main cyber-content" localeHrefs={localeHrefs}>
16
+ <link slot="head" rel="stylesheet" href="/styles/theme-cyber.css" />
16
17
  <Fragment slot="body-start">
17
18
  <div class="cyber-load-glitch" aria-hidden="true"></div>
18
19
  <div class="cyber-spotlight" aria-hidden="true">