@anglefeint/astro-theme 0.1.12 → 0.1.14

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.
package/package.json CHANGED
@@ -1,8 +1,17 @@
1
1
  {
2
2
  "name": "@anglefeint/astro-theme",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "description": "Anglefeint core theme package for Astro",
6
+ "keywords": [
7
+ "astro",
8
+ "astro-theme",
9
+ "blog",
10
+ "portfolio",
11
+ "cyberpunk",
12
+ "hacker",
13
+ "matrix"
14
+ ],
6
15
  "license": "MIT",
7
16
  "files": [
8
17
  "src/index.ts",
@@ -16,8 +25,7 @@
16
25
  "src/styles",
17
26
  "src/assets/theme",
18
27
  "src/cli-new-post.mjs",
19
- "src/cli-new-page.mjs",
20
- "public"
28
+ "src/cli-new-page.mjs"
21
29
  ],
22
30
  "bin": {
23
31
  "anglefeint-new-post": "src/cli-new-post.mjs",
@@ -31,7 +39,6 @@
31
39
  "./i18n/*": "./src/i18n/*",
32
40
  "./styles/*": "./src/styles/*",
33
41
  "./assets/*": "./src/assets/*",
34
- "./public/*": "./public/*",
35
42
  "./content-schema": "./src/content-schema.ts",
36
43
  "./consts": "./src/consts.ts"
37
44
  },
@@ -15,10 +15,11 @@ const { tagline = SITE_TAGLINE, scanlines = false } = Astro.props as Props;
15
15
 
16
16
  <footer>
17
17
  &copy; {today.getFullYear()} {SITE_TITLE}. {tagline}
18
- {SOCIAL_LINKS.length > 0 && (
19
- <div class="social-links">
20
- <SocialMenu links={SOCIAL_LINKS} />
21
- </div>
18
+ <div class="social-links">
19
+ <SocialMenu links={SOCIAL_LINKS} />
20
+ </div>
21
+ {import.meta.env.DEV && SOCIAL_LINKS.length === 0 && (
22
+ <p class="social-hint">Configure social links in <code>src/site.config.ts</code></p>
22
23
  )}
23
24
  {scanlines && <div class="ai-scanlines" aria-hidden="true"></div>}
24
25
  </footer>
@@ -36,6 +37,16 @@ const { tagline = SITE_TAGLINE, scanlines = false } = Astro.props as Props;
36
37
  gap: 1em;
37
38
  margin-top: 1em;
38
39
  }
40
+ .social-hint {
41
+ margin: 0.6rem 0 0;
42
+ font-size: 0.78rem;
43
+ color: var(--chrome-text-muted, rgb(var(--text-muted)));
44
+ opacity: 0.82;
45
+ }
46
+ .social-hint code {
47
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
48
+ font-size: 0.75rem;
49
+ }
39
50
  .social-links a {
40
51
  text-decoration: none;
41
52
  color: var(--chrome-text-muted, rgb(var(--text-muted)));
@@ -151,53 +151,17 @@ const localeOptions = SUPPORTED_LOCALES.map((targetLocale) => ({
151
151
  gap: 0.4rem;
152
152
  position: relative;
153
153
  flex-wrap: nowrap;
154
- }
155
- .lang-switcher {
156
- display: inline-flex;
157
- align-items: center;
158
- gap: 0.4rem;
159
- padding: 0.2rem 0.4rem;
160
- margin-right: 0.1rem;
161
- border: 1px solid rgba(132, 214, 255, 0.2);
162
- border-radius: 999px;
163
- background: rgba(6, 16, 30, 0.35);
164
- flex-shrink: 0;
165
- }
166
- .lang-label {
167
- display: inline-block;
168
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
169
- font-size: 0.6rem;
170
- text-transform: uppercase;
171
- letter-spacing: 0.12em;
172
- color: rgba(190, 226, 248, 0.78);
173
- white-space: nowrap;
174
- }
175
- .lang-select {
176
- appearance: none;
177
- -webkit-appearance: none;
178
- -moz-appearance: none;
179
- background:
180
- linear-gradient(45deg, transparent 50%, rgba(204, 236, 252, 0.82) 50%) calc(100% - 0.9rem) 50% / 0.35rem 0.35rem no-repeat,
181
- linear-gradient(135deg, rgba(204, 236, 252, 0.82) 50%, transparent 50%) calc(100% - 0.7rem) 50% / 0.35rem 0.35rem no-repeat,
182
- rgba(9, 22, 40, 0.68);
183
- border: 1px solid rgba(132, 214, 255, 0.2);
184
- border-radius: 999px;
185
- padding: 0.2rem 1.45rem 0.2rem 0.55rem;
186
- min-width: 6rem;
187
- font-size: 0.62rem;
188
- line-height: 1;
189
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
190
- color: rgba(204, 236, 252, 0.86);
191
- cursor: pointer;
192
- }
193
- .lang-select:focus {
194
- outline: none;
195
- border-color: rgba(132, 214, 255, 0.5);
196
- box-shadow: 0 0 0 2px rgba(98, 180, 228, 0.18);
197
- }
198
- .lang-select option {
199
- color: #ccecfb;
200
- background: #0b1c32;
154
+ --lang-switcher-border: rgba(132, 214, 255, 0.2);
155
+ --lang-switcher-bg: rgba(6, 16, 30, 0.35);
156
+ --lang-label-color: rgba(190, 226, 248, 0.78);
157
+ --lang-select-arrow: rgba(204, 236, 252, 0.82);
158
+ --lang-select-bg: rgba(9, 22, 40, 0.68);
159
+ --lang-select-border: rgba(132, 214, 255, 0.2);
160
+ --lang-select-text: rgba(204, 236, 252, 0.86);
161
+ --lang-select-focus-border: rgba(132, 214, 255, 0.5);
162
+ --lang-select-focus-ring: rgba(98, 180, 228, 0.18);
163
+ --lang-select-option-text: #ccecfb;
164
+ --lang-select-option-bg: #0b1c32;
201
165
  }
202
166
  .nav-status {
203
167
  display: none;
@@ -33,3 +33,60 @@ const { label, currentLocale, options } = Astro.props as Props;
33
33
  }
34
34
  </select>
35
35
  </div>
36
+
37
+ <style>
38
+ .lang-switcher {
39
+ display: inline-flex;
40
+ align-items: center;
41
+ gap: 0.4rem;
42
+ padding: 0.2rem 0.4rem;
43
+ margin-right: 0.1rem;
44
+ border: 1px solid var(--lang-switcher-border, rgba(132, 214, 255, 0.2));
45
+ border-radius: 999px;
46
+ background: var(--lang-switcher-bg, rgba(6, 16, 30, 0.35));
47
+ flex-shrink: 0;
48
+ }
49
+ .lang-label {
50
+ display: inline-block;
51
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
52
+ font-size: 0.6rem;
53
+ text-transform: uppercase;
54
+ letter-spacing: 0.12em;
55
+ color: var(--lang-label-color, rgba(190, 226, 248, 0.78));
56
+ white-space: nowrap;
57
+ }
58
+ .lang-select {
59
+ appearance: none;
60
+ -webkit-appearance: none;
61
+ -moz-appearance: none;
62
+ background:
63
+ linear-gradient(45deg, transparent 50%, var(--lang-select-arrow, rgba(204, 236, 252, 0.82)) 50%) calc(100% - 0.9rem) 50% /
64
+ 0.35rem 0.35rem no-repeat,
65
+ linear-gradient(135deg, var(--lang-select-arrow, rgba(204, 236, 252, 0.82)) 50%, transparent 50%) calc(100% - 0.7rem) 50% /
66
+ 0.35rem 0.35rem no-repeat,
67
+ var(--lang-select-bg, rgba(9, 22, 40, 0.68));
68
+ border: 1px solid var(--lang-select-border, rgba(132, 214, 255, 0.2));
69
+ border-radius: 999px;
70
+ padding: 0.2rem 1.45rem 0.2rem 0.55rem;
71
+ min-width: 6rem;
72
+ font-size: 0.62rem;
73
+ line-height: 1;
74
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
75
+ color: var(--lang-select-text, rgba(204, 236, 252, 0.86));
76
+ cursor: pointer;
77
+ }
78
+ .lang-select:focus {
79
+ outline: none;
80
+ border-color: var(--lang-select-focus-border, rgba(132, 214, 255, 0.5));
81
+ box-shadow: 0 0 0 2px var(--lang-select-focus-ring, rgba(98, 180, 228, 0.18));
82
+ }
83
+ .lang-select option {
84
+ color: var(--lang-select-option-text, #ccecfb);
85
+ background: var(--lang-select-option-bg, #0b1c32);
86
+ }
87
+ @media (max-width: 720px) {
88
+ .lang-switcher {
89
+ margin-right: 0;
90
+ }
91
+ }
92
+ </style>
@@ -5,16 +5,44 @@ import Icon from './Icon.astro';
5
5
  interface Props {
6
6
  links?: SocialLink[];
7
7
  iconSize?: number;
8
+ showPlaceholdersWhenEmpty?: boolean;
8
9
  }
9
10
 
10
- const { links = SOCIAL_LINKS, iconSize = 32 } = Astro.props as Props;
11
+ const {
12
+ links = SOCIAL_LINKS,
13
+ iconSize = 32,
14
+ showPlaceholdersWhenEmpty = true,
15
+ } = Astro.props as Props;
16
+ const placeholderLinks: SocialLink[] = [
17
+ { href: '', label: 'Mastodon', icon: 'mastodon' },
18
+ { href: '', label: 'Twitter', icon: 'twitter' },
19
+ { href: '', label: 'GitHub', icon: 'github' },
20
+ ];
21
+ const resolvedLinks = links.length > 0 || !showPlaceholdersWhenEmpty ? links : placeholderLinks;
11
22
  ---
12
23
 
13
24
  {
14
- links.map((link) => (
15
- <a href={link.href} target="_blank" rel="noopener noreferrer">
16
- <span class="sr-only">{link.label}</span>
17
- {link.icon ? <Icon name={link.icon} size={iconSize} /> : <span>{link.label}</span>}
18
- </a>
25
+ resolvedLinks.map((link) => (
26
+ links.length > 0 ? (
27
+ <a href={link.href} target="_blank" rel="noopener noreferrer">
28
+ <span class="sr-only">{link.label}</span>
29
+ {link.icon ? <Icon name={link.icon} size={iconSize} /> : <span>{link.label}</span>}
30
+ </a>
31
+ ) : (
32
+ <span class="social-placeholder" aria-hidden="true" title="Configure social links in src/site.config.ts">
33
+ {link.icon ? <Icon name={link.icon} size={iconSize} /> : <span>{link.label}</span>}
34
+ </span>
35
+ )
19
36
  ))
20
37
  }
38
+
39
+ <style>
40
+ .social-placeholder {
41
+ display: inline-flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ opacity: 0.45;
45
+ filter: saturate(0.7);
46
+ cursor: default;
47
+ }
48
+ </style>
@@ -5,6 +5,7 @@ import themeRedqueen1 from '../assets/theme/red-queen/theme-redqueen1.webp';
5
5
  import themeRedqueen2 from '../assets/theme/red-queen/theme-redqueen2.gif';
6
6
  import FormattedDate from '../components/FormattedDate.astro';
7
7
  import AiShell from './shells/AiShell.astro';
8
+ import blogPostCssUrl from '../styles/blog-post.css?url';
8
9
  import { SITE_AUTHOR } from '@anglefeint/site-config/site';
9
10
  import { DEFAULT_LOCALE, type Locale, isLocale, localePath, blogIdToSlugAnyLocale } from '@anglefeint/site-i18n/config';
10
11
  import { getMessages } from '@anglefeint/site-i18n/messages';
@@ -62,7 +63,7 @@ const confidenceText = aiConfidence !== undefined ? aiConfidence.toFixed(2) : un
62
63
  tags={tags}
63
64
  localeHrefs={localeHrefs}
64
65
  >
65
- <link slot="head" rel="stylesheet" href="/styles/blog-post.css" />
66
+ <link slot="head" rel="stylesheet" href={blogPostCssUrl} />
66
67
  <Fragment slot="body-start">
67
68
  <div class="ai-bg" aria-hidden="true">
68
69
  <div class="ai-glow ai-glow-shift"></div>
@@ -2,6 +2,7 @@
2
2
  import type { Locale } from '@anglefeint/site-i18n/config';
3
3
  import ThemeFrame from '../../components/shared/ThemeFrame.astro';
4
4
  import type { ImageMetadata } from 'astro';
5
+ import themeAiCssUrl from '../../styles/theme-ai.css?url';
5
6
 
6
7
  interface Props {
7
8
  locale?: Locale;
@@ -51,7 +52,7 @@ const {
51
52
  scanlines
52
53
  localeHrefs={localeHrefs}
53
54
  >
54
- <link slot="head" rel="stylesheet" href="/styles/theme-ai.css" />
55
+ <link slot="head" rel="stylesheet" href={themeAiCssUrl} />
55
56
  <slot name="head" slot="head" />
56
57
  <slot name="body-start" slot="body-start" />
57
58
  <slot />
@@ -1,6 +1,8 @@
1
1
  ---
2
2
  import type { Locale } from '@anglefeint/site-i18n/config';
3
3
  import ThemeFrame from '../../components/shared/ThemeFrame.astro';
4
+ import themeCyberCssUrl from '../../styles/theme-cyber.css?url';
5
+ import blogListCssUrl from '../../styles/blog-list.css?url';
4
6
 
5
7
  interface Props {
6
8
  locale?: Locale;
@@ -13,7 +15,8 @@ const { locale, title, description, localeHrefs } = Astro.props as Props;
13
15
  ---
14
16
 
15
17
  <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" />
18
+ <link slot="head" rel="stylesheet" href={themeCyberCssUrl} />
19
+ <link slot="head" rel="stylesheet" href={blogListCssUrl} />
17
20
  <Fragment slot="body-start">
18
21
  <div class="cyber-load-glitch" aria-hidden="true"></div>
19
22
  <div class="cyber-spotlight" aria-hidden="true">
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import type { Locale } from '@anglefeint/site-i18n/config';
3
3
  import ThemeFrame from '../../components/shared/ThemeFrame.astro';
4
+ import aboutPageCssUrl from '../../styles/about-page.css?url';
4
5
 
5
6
  interface Props {
6
7
  locale?: Locale;
@@ -13,7 +14,7 @@ const { locale, title, description, bodyClass = 'hacker-page' } = Astro.props as
13
14
  ---
14
15
 
15
16
  <ThemeFrame locale={locale} title={title} description={description} bodyClass={bodyClass} mainClass="page-main hacker-content">
16
- <link slot="head" rel="stylesheet" href="/styles/about-page.css" />
17
+ <link slot="head" rel="stylesheet" href={aboutPageCssUrl} />
17
18
  <slot name="head" slot="head" />
18
19
  <slot name="body-start" slot="body-start" />
19
20
  <slot />
@@ -1,6 +1,7 @@
1
1
  ---
2
2
  import type { Locale } from '@anglefeint/site-i18n/config';
3
3
  import ThemeFrame from '../../components/shared/ThemeFrame.astro';
4
+ import homePageCssUrl from '../../styles/home-page.css?url';
4
5
 
5
6
  interface Props {
6
7
  locale?: Locale;
@@ -12,7 +13,7 @@ const { locale, title, description } = Astro.props as Props;
12
13
  ---
13
14
 
14
15
  <ThemeFrame locale={locale} title={title} description={description} bodyClass="page-home" mainClass="page-main home-content">
15
- <link slot="head" rel="stylesheet" href="/styles/home-page.css" />
16
+ <link slot="head" rel="stylesheet" href={homePageCssUrl} />
16
17
  <canvas slot="body-start" id="matrix-bg" aria-hidden="true"></canvas>
17
18
  <Fragment slot="body-end">
18
19
  <script>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes